虫食算(洛谷-P1092)
生活随笔
收集整理的這篇文章主要介紹了
虫食算(洛谷-P1092)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述
所謂蟲食算,就是原先的算式中有一部分被蟲子啃掉了,需要我們根據剩下的數字來判定被啃掉的字母。
現在,我們對問題做兩個限制:
首先,我們只考慮加法的蟲食算。這里的加法是N進制加法,算式中三個數都有N位,允許有前導的0。
其次,蟲子把所有的數都啃光了,我們只知道哪些數字是相同的,我們將相同的數字用相同的字母表示,不同的數字用不同的字母表示。如果這個算式是N進制的,我們就取英文字母表午的前N個大寫字母來表示這個算式中的0到N-1這N個不同的數字:但是這N個字母并不一定順序地代表0到N-1)。輸入數據保證N個字母分別至少出現一次。
上面的算式是一個4進制的算式。很顯然,我們只要讓ABCD分別代表0123,便可以讓這個式子成立了。你的任務是,對于給定的N進制加法算式,求出N個不同的字母分別代表的數字,使得該加法算式成立。輸入數據保證有且僅有一組解
輸入輸出格式
輸入格式:
包含四行。第一行有一個正整數N(N<=26),后面的3行每行有一個由大寫字母組成的字符串,分別代表兩個加數以及和。這3個字符串左右兩端都沒有空格,從高位到低位,并且恰好有N位。
輸出格式:
包含一行。在這一行中,應當包含唯一的那組解。解是這樣表示的:輸出N個數字,分別表示A,B,C……所代表的數字,相鄰的兩個數字用一個空格隔開,不能有多余的空格。
輸入輸出樣例
輸入樣例#1:
5
ABCED
BDACE
EBBAA
輸出樣例#1:
1 0 3 4 2
源代碼
#include<string> #include<iostream> #include<cstring> using namespace std; int n; int res[26];//保存A.B..Z代表的數字 int used[26];//保存這個對應數字是否被用 string a,b,c;//保存加數1,加數2,和 int flag=0; char pos[26]; int used_letter[26];//保存用過的字母int Check() {int i;for (i=n-1;i>=0;i--)//判斷是否滿足a+b=c{char a1=a[i]-'A',b1=b[i]-'A',c1=c[i]-'A';//取三個數第i位置值if(res[a1]!=-1 && res[b1]!=-1 && res[c1]!=-1)//3個數都知道{if( (res[a1]+res[b1])%n!=res[c1] && (res[a1]+res[b1]+1)%n!=res[c1])//無進位與有進位return 0;}if(res[a1]!=-1 && res[b1]!=-1 && res[c1]==-1)//知道2個數{int sum1,sum2;//sum1無進位,sum2有進位sum1=(res[a1]+res[b1])%n;sum2=(res[a1]+res[b1]+1)%n;if(used[sum1] && used[sum2])return 0;}if(res[a1]!=-1 && res[b1]==-1 && res[c1]!=-1)//知道和與一個加數{int js1,js2;//js1無進位,js2有進位js1=(res[c1]-res[a1]+n)%n;js2=(res[c1]-res[a1]-1+n)%n;if (used[js1] && used[js2])return 0;}if(res[a1]==-1 && res[b1]!=-1 && res[c1]!=-1)//知道和與另一個加數{int js1,js2;//js1無進位,js2有進位js1 = (res[c1]-res[b1]+n)%n;js2 = (res[c1]-res[b1]-1+n)%n;if (used[js1] && used[js2])return 0;}}return 1; }int OK() {int i;int carry=0;//進位int sum;//和for (i=n-1; i>=0; i--){char a1=a[i]-'A',b1=b[i]-'A',c1=c[i]-'A';sum = (res[a1]+res[b1]+carry)%n;//計算和carry =( res[a1]+res[b1]+carry)/n;//計算進位if (sum!=res[c1])return 0;}if (carry>0)return 0;return 1; } void dfs(int k)//深搜 {int i;if (flag)return;if (!Check())return;if(k==n){if (OK())//如果當前所有字母填數滿足等式則輸出{for(i=0; i<=n-2; i++)cout<<res[i]<<' ';cout<<res[n-1]<<endl;flag=1;}return ;}for (i=n-1; i>=0; i--){if (!used[i])//如果i還沒被占用,且滿足剪枝條件,則進行下層遍歷{used[i]=1;res[pos[k]]=i;dfs(k+1);used[i]=0;res[pos[k]]=-1;}}return ; }int main() {int k=0,i;cin>>n;cin>>a>>b>>c;memset(res,-1,sizeof(res));memset(pos,-1,sizeof(pos));for (i=n-1; i>=0; i--)//從右向左{char a1=a[i]-'A',b1=b[i]-'A',c1=c[i]-'A';//全部轉成對應數字下標if (!used_letter[a1])//從上往下{used_letter[a1]=1;pos[k++] = a1;}if (!used_letter[b1]){used_letter[b1]=1;pos[k++] = b1;}if (!used_letter[c1]){used_letter[c1]=1;pos[k++] = c1;}}dfs(0);return 0; }?
總結
以上是生活随笔為你收集整理的虫食算(洛谷-P1092)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 凌乱的yyy(洛谷-P1803)
- 下一篇: 菲波那契数列(信息学奥赛一本通-T120