【搜索】$P1092$虫食算
【搜索】\(P1092\)蟲食算
題目鏈接
首先,我們只考慮加法的蟲食算。這里的加法是N進(jìn)制加法,算式中三個(gè)數(shù)都有N位,允許有前導(dǎo)的0。
其次,蟲子把所有的數(shù)都啃光了,我們只知道哪些數(shù)字是相同的,我們將相同的數(shù)字用相同的字母表示,不同的數(shù)字用不同的字母表示。如果這個(gè)算式是N進(jìn)制的,我們就取英文字母表午的前N個(gè)大寫字母來表示這個(gè)算式中的0到N-1這N個(gè)不同的數(shù)字:但是這N個(gè)字母并不一定順序地代表0到N-1。輸入數(shù)據(jù)保證N個(gè)字母分別至少出現(xiàn)一次。輸入數(shù)據(jù)保證有且僅有一組解。
輸入格式
包含四行。
第一行有一個(gè)正整數(shù)\(N(N \leq 26)\)。
后面的三行,每行有一個(gè)由大寫字母組成的字符串,分別代表兩個(gè)加數(shù)以及和。這3個(gè)字符串左右兩端都沒有空格,從高位到低位,并且恰好有N位。
輸出格式
一行,即唯一的那組解。
解是這樣表示的:輸出N個(gè)數(shù)字,分別表示A,B,C,…所代表的數(shù)字,相鄰的兩個(gè)數(shù)字用一個(gè)空格隔開,不能有多余的空格。
對(duì)于30%的數(shù)據(jù),保證有\(N \leq 10\);
對(duì)于50%的數(shù)據(jù),保證有\(N \leq 15\);
對(duì)于全部的數(shù)據(jù),保證有\(N \leq 26\)。
Solution
搜索是比較好想的。但若直接枚舉全排列需要n!,那么需要剪枝。
考慮加法,進(jìn)位的話只會(huì)進(jìn)1,所以如果(A + B) % n != C && (A + B +1) % n != C,顯然不合法。然后因?yàn)槿齻€(gè)數(shù)都是N位,所以最高位不可能進(jìn)位。
那么什么搜索順序會(huì)更優(yōu)呢?從右往左,也就是從低位到高位。從右往左,按照字母出現(xiàn)順序搜索,能在很大程度上提高剪枝效率。
最后,最關(guān)鍵的一點(diǎn),是一個(gè)exit(0)的應(yīng)用。第一次知道這到底是個(gè)什么。
exit(0):正常運(yùn)行程序并退出程序。 exit 是一個(gè)函數(shù)。 exit是系統(tǒng)調(diào)用級(jí)別的,它表示了一個(gè)進(jìn)程的結(jié)束。 exit是進(jìn)程的退出。 exit是操作系統(tǒng)提供的(或者函數(shù)庫(kù)中給出的)。 exit函數(shù)是退出應(yīng)用程序,刪除進(jìn)程使用的內(nèi)存空間,并將應(yīng)用程序的一個(gè)狀態(tài)返回給OS,這個(gè)狀態(tài)標(biāo)識(shí)了應(yīng)用程序的一些運(yùn)行信息,這個(gè)信息和機(jī)器和操作系統(tǒng)有關(guān),一般是 0 為正常退出,非0 為非正常退出。 6. 非主函數(shù)中調(diào)用return和exit效果很明顯,但是在main函數(shù)中調(diào)用return和exit的現(xiàn)象就很模糊,多數(shù)情況下現(xiàn)象都是一致的。
#include <algorithm> #include <iostream> #include <cstdio> using namespace std; long long read(){long long x = 0; int f = 0; char c = getchar();while(c < '0' || c > '9') f |= c == '-', c = getchar();while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();return f? -x:x; }int a[30], b[30], c[30], num[30], qu[30], n, cnt; char s1[30], s2[30], s3[30]; bool used[30]; bool ok(){//最后判斷一下是否滿足等式for(int i = n - 1, x = 0; i >= 0; --i){int A = num[a[i]], B = num[b[i]], C = num[c[i]];if((A + B + x) % n != C) return 0;x = (A + B + x) / n;}return 1; } void print(){//輸出printf("%d", num[0]);for(int i = 1; i < n; ++i) printf(" %d", num[i]);exit(0);//減少遞歸返回時(shí)間 } void dfs(int x){if(num[a[0]] + num[b[0]] >= n) return;//最高位沒有進(jìn)位for(int i = n - 1; i >= 0; --i){int A = num[a[i]], B = num[b[i]], C = num[c[i]];if(A == -1 || B == -1 || C == -1) continue;if((A + B) % n != C && (A + B + 1) % n != C) return;//判每一位是否合法}if(x == n){if(ok()) print();return;}for(int i = n - 1; i >= 0; --i)if(!used[i]){num[qu[x]] = i, used[i] = 1;dfs(x + 1);num[qu[x]] = -1, used[i] = 0;//回溯} } void Sort(int x){//預(yù)處理遞歸枚舉順序if(!used[x]) used[x] = 1, qu[cnt++] = x; } int main(){freopen("1.txt", "r", stdin);freopen("1.out", "w", stdout);n = read();scanf("%s%s%s", s1, s2, s3);for(int i = 0; i < n; ++i)a[i] = s1[i] - 'A', b[i] = s2[i] - 'A', c[i] = s3[i] - 'A', num[i] = -1;for(int i = n - 1; i >= 0; --i){Sort(a[i]);//預(yù)處理順序Sort(b[i]);Sort(c[i]);}for(int i = 0; i < n; ++i) used[i] = 0;dfs(0);return 0; }轉(zhuǎn)載于:https://www.cnblogs.com/kylinbalck/p/11307087.html
總結(jié)
以上是生活随笔為你收集整理的【搜索】$P1092$虫食算的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 爬虫之基于线程池异步抓取
- 下一篇: PAT乙级1023