P1092 蟲食算 題解(dfs 深度優先搜尋)

2021-09-25 14:43:52 字數 3003 閱讀 8858

所謂蟲食算,就是原先的算式中有一部分被蟲子啃掉了,需要我們根據剩下的數字來判定被啃掉的字母。來看乙個簡單的例子:

43#9865#045

+ 8468#6633

44445509678

其中#號代表被蟲子啃掉的數字。根據算式,我們很容易判斷:第一行的兩個數字分別是55和33,第二行的數字是55。

現在,我們對問題做兩個限制:

首先,我們只考慮加法的蟲食算。這裡的加法是nn進製加法,算式中三個數都有nn位,允許有前導的00。

其次,蟲子把所有的數都啃光了,我們只知道哪些數字是相同的,我們將相同的數字用相同的字母表示,不同的數字用不同的字母表示。如果這個算式是nn進製的,我們就取英文本母表午的前nn個大寫字母來表示這個算式中的00到n-1n−1這nn個不同的數字:但是這nn個字母並不一定順序地代表00到n-1n−1。輸入資料保證nn個字母分別至少出現一次。

badc

+cbda

dccc

上面的算式是乙個4進製的算式。很顯然,我們只要讓abcdabcd分別代表01230123,便可以讓這個式子成立了。你的任務是,對於給定的nn進製加法算式,求出nn個不同的字母分別代表的數字,使得該加法算式成立。輸入資料保證有且僅有一組解。

輸入格式

包含四行。

第一行有乙個正整數n(n \le 26)n(n≤26)。

後面的三行,每行有乙個由大寫字母組成的字串,分別代表兩個加數以及和。這3個字串左右兩端都沒有空格,從高位到低位,並且恰好有nn位。

輸出格式

一行,即唯一的那組解。

解是這樣表示的:輸出nn個數字,分別表示a,b,c,…a,b,c,…所代表的數字,相鄰的兩個數字用乙個空格隔開,不能有多餘的空格。

輸入輸出樣例

輸入

5

abced

bdace

ebbaa

輸出

1 0 3 4 2
說明/提示

對於30%的資料,保證有n \le 10n≤10;

對於50%的資料,保證有n \le 15n≤15;

對於全部的資料,保證有n \le 26n≤26。

我剛開始是乙個字母乙個字母去判斷,儘管做了部分剪枝,依然存在超時。我最初的思路是用乙個map去裝載每個單詞及對應的值,然後dfs全排列對字母進行組合,唯一的剪枝操作是對前兩個式子之和與結果每一位進行對比,但是顯然不夠。最後發現有人在已知三個字母時就開始判斷這一列,之和不等於結果就可以直接pass。這樣,效率就可以大大提公升。

詳細解體思路請見**的注釋。

超時**

#include

#include

#include

#include

using namespace std;

int n;

string f[3]

;string word =

"abcdefghijklmnopqrstuvwxyz"

;map<

char

,int

> num;

//使用map記錄單詞和其對應的值

int vis[30]

;bool check()

if(s != num.

find

(f[2

][i]

)->second)

return false;

sum1 +

= s*(10

^(n-i-1)

);if(ad)

sum2 +

= num.

find

(f[2

][i]

)->second*(10

^(n-i-1)

);}return true;

}void

dfs(

int r)

else

printf

("%d"

,num[word[i]])

;}cout

);}else

return;}

for(

int i = n-

1;i >=

0;i--)}

}int

main()

dfs(0)

;return0;

}

ac**

#include

#include

const

int n =30;

int n;

int a[n]

,b[n]

,c[n]

;//記錄三個式子**現的字母

int vis[n]

;//訪問標記

int ans[n]

;char s[3]

[n];

int seq[n]

;//搜尋順序按照第乙個字串的順序

void

dfs(

int r)

if(r == n)

for(i =

0;i < n;i++

)printf

("%d "

,ans[i]);

exit(0

);//輸出後,退出程式,避免繼續執行導致超時

}for

(i = n-

1;i >=

0;i--)}

}int cnt;

voidf(

int i)

}int

main()

for(i = n-

1;i >=

0;i--

)for

(i =

0;i < n;i++

) vis[i]=0

;dfs(0

);return0;

}

p1092

P1092 蟲食算 題解 DFS 深度優先搜尋

這道題一開始自己寫的時候,只有30分 然後參 模 考 仿 了洛谷第乙個題解才寫出來了 不過是在理解了的前提下,自己敲了一遍 下面附上參考的題解部落格位址 參考的題解部落格 我的 include using namespace std int n,cnt char s1 50 s2 50 s3 50 ...

題解 P1092 蟲食算

聽說正解是高斯消元吶,但是我不會 看到大家都寫了搜尋。一種實現很簡單的方法是列舉1 n的排列,判斷是否可行。我算了算時間複雜度 其實我不會算,就大概估計了一下 發現會超時。由於不會算複雜度,我對於這樣的暴搜能過50表示驚訝 o 如果按照豎式從右至左的順序搜,就可以邊搜邊判斷是否可行了。我寫得很麻煩,...

洛谷 P1092 蟲食算(dfs)

題目傳送 這題的官方題解是高斯消元,可是本蒟蒻不會。講一下深搜的方法 1.搜尋從第一位的值開始搜,直到最後一位,判斷是否合法。2.注意剪枝防tle。3.三個數都是n位,最高位不能有進製。include include include using namespace std const int max...