洛谷 p1092 虫食算
题目链接: https://www.luogu.org/problemnew/show/P1092
这个题折腾了我好久 这其实本质上是一道凑算式的题目 ,让一个二维数组存算式,一个一位数组存字母分别代表哪个数字。需要注意的是数位还有位置的标号的问题 究竟是0-n还是1-n还是0-(n-1),这是需要仔细考虑的问题。
直接上代码吧
#include<bits/stdc++.h> using namespace std; char ss[4][30]; int n,flag[30],s[4][30],vis[30]; void dfs(int x,int y,int t) { if(x==0) { if(t==0) { for(int i=1;i<n;i++) cout<<flag[i]<<" "; cout<<flag[n]; exit(0); } return; } for(int i=x-1;i>=1;i--) //剪枝,一旦不适合就返回 { int a=flag[s[1][i]]; int b=flag[s[2][i]]; int c=flag[s[3][i]]; if(a==-1||b==-1||c==-1) //还没有赋值的先不管他 continue; if((a+b)%n!=c&&(a+b+1)%n!=c) return; } if(flag[s[y][x]]==-1) //如果这一位的字母还没有赋值 { for(int i=n-1;i>=0;i--) //要注意 取值是0到n-1 if(vis[i]==0) { if(y!=3) //最后一行和其他的有不同 要分开讨论 { flag[s[y][x]]=i;vis[i]=1; dfs(x,y+1,t); flag[s[y][x]]=-1;vis[i]=0; } else { int w=flag[s[1][x]]+flag[s[2][x]]+t; if(w%n!=i) continue; flag[s[3][x]]=i;vis[i]=1; dfs(x-1,1,w/n); flag[s[3][x]]=-1; vis[i]=0; } } } else //如果已经赋值 { if(y!=3) dfs(x,y+1,t); else { int w=flag[s[1][x]]+flag[s[2][x]]+t; if (w%n!=flag[s[3][x]]) //剪枝 return; dfs(x-1,1,w/n); } } } int main() { cin>>n; int i,j; for(i=0;i<3;i++) { cin>>ss[i]; } for(i=1;i<=3;i++) for(j=1;j<=n;j++) { s[i][j]=ss[i-1][j-1]-'A'+1; //为了方便使用 我直接让角标从1开始 } memset(flag,-1,sizeof(flag)); dfs(n,1,0); }