虫食算
因为太懒了所以不概括题意了(懒得调格式 copy下来很丑)
思路: 其实最朴素的很好想啦
就是枚举每个字母所代表的数 然后check
优化就是尽量从低位开始赋值 这样可以更早检验并排除错误答案
这里一个预处理就可以啦
数组有很多 一定不能晕了
However,我的代码仍然有少数超时的点
So 待修正完善的 CODE
#include<iostream> #include<cstdio> #include<string> #include<cstdlib> #define go(i,a,b) for(register int i=a;i<=b;i++) #define goo(i,a,b) for(register int i=a;i>=b;i--) #define M 30 using namespace std; int read() { int x=0,y=1;char c=getchar(); while(c<'0'||c>'9') {if(c=='-') y=-1;c=getchar();} while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-'0';c=getchar();} return x*y; } int n,a[3][M],b[M],cnt,ccnt,n_ans[M],f_ans[M]; bool fg[M]; string s; void putin() { n=read(); go(i,0,2) {cin>>s; go(k,1,n) a[i][k]=s[n-k]-'A'+1;} go(i,1,n) { if(!b[a[0][i]]) b[a[0][i]]=++cnt; if(!b[a[1][i]]) b[a[1][i]]=++cnt; if(!b[a[2][i]]) b[a[2][i]]=++cnt; } go(i,0,2) go(j,1,n) a[i][j]=b[a[i][j]]; } bool ck() { int x,y,z; go(i,1,n) { x=n_ans[a[0][i]];y=n_ans[a[1][i]];z=n_ans[a[2][i]]; if(x&&y&&z&&((x+y)%n!=z)&&((x+y+1)%n!=z)) return 0; } return 1; } bool f_ck() { int x,y,z,k=0; go(i,1,n) { x=n_ans[a[0][i]];y=n_ans[a[1][i]];z=n_ans[a[2][i]]; if((x+y+k)%n!=z) return 0; k=(x+y+k)/n; } if(k) return 0; return 1; } void print() { go(i,1,n-1) printf("%d ",f_ans[b[i]]); printf("%d",f_ans[b[n]]); } void dfs(int nw) { if(nw==n) { if(f_ck()) {go(i,1,n) f_ans[i]=n_ans[i];print();exit(0);} else return ; } if(!ck()) return ; goo(i,n-1,0) { if(!fg[i]) {fg[i]=1;n_ans[nw+1]=i;dfs(nw+1);n_ans[nw+1]=0;fg[i]=0;} } return ; } int main() { //freopen("alpha.in","r",stdin); //freopen("alpha.out","w",stdout); putin(); dfs(0); return 0; }
Then 再附上我以前写的AC CODE
#include<iostream> #include<cstdio> #include<cstdlib> using namespace std; int n; int a[30],b[30],c[30];//下标为位数(1~n-1) 从右往左 值为未知数(1~n-1) int p[30]; void read(int x[]) { char ch; for(int i=n;i>=1;i--) { ch=getchar(); while(ch<'A'||ch>'Z') ch=getchar(); x[i]=ch-'A'+1; } } int d[30];//下标为字母转换成的数字 相当于未知数吧 值为未知数的值(0~n-1) int used[30];//下标为具体值 bool Judge() { for(int i=1;i<=n;i++) //第i位 { int x1=a[i],y1=b[i],z1=c[i]; if(d[x1]==-1||d[y1]==-1||d[z1]==-1) continue ; if(((d[x1]+d[y1])%n!=d[z1])&&((d[x1]+d[y1]+1)%n!=d[z1])) return 0; } return 1; } bool F_Judge() { int y=0; for(int i=1;i<=n;i++) { int x1=a[i],y1=b[i],z1=c[i]; if((d[x1]+d[y1]+y)%n!=d[z1]) return 0; y=(d[x1]+d[y1]+y)/n; } return 1; } void print() { for(int i=1;i<=n;i++) printf("%d ",d[i]); } void dfs(int x) { if(x>n) { if(F_Judge()) {print();exit(0);} return ; } for(int i=n-1;i>=0;i--) //i:具体值 { if(used[i]) continue; d[p[x]]=i; if(!Judge()) continue; used[i]=1; dfs(x+1); used[i]=0; } d[p[x]]=-1; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) d[i]=-1; read(a);read(b);read(c); int num=0; for(int i=1;i<=n;i++) { if(!used[a[i]]) {p[++num]=a[i];used[a[i]]=1;} if(!used[b[i]]) {p[++num]=b[i];used[b[i]]=1;} if(!used[c[i]]) {p[++num]=c[i];used[c[i]]=1;} } for(int i=1;i<=n;i++) used[i]=0; dfs(1); return 0; }
光伴随的阴影