4793: 虫食算 noip2004提高组T4 深搜/剪枝
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e3+10,inf = 0x3f3f3f3f; char A[N],B[N],C[N]; char words[N]; int cnt; char keys[N]; bool vis[N]; int n; void print() { for(int i = 0; i < n - 1; i++) printf("%d ",keys[i]); printf("%d\n",keys[n - 1]); } void change(char *str,char f,char t) { for(int i = 1; i <= n; i++) str[i] = (str[i] == f ? t : str[i]); } bool check1() { int res = 0; for(int i = n; i >= 1; i--) { if(A[i] >= n || B[i] >= n || C[i] >= n)return 1; res = A[i] + B[i] + res; if(res % n != C[i])return 0; res /= n; } return 1; } bool check2() { int p,p1,p2; for(int i = n; i >= 1; i--) //a,b,c { if(A[i] >= n || B[i] >= n || C[i] >= n) continue; p = (A[i] + B[i]) % n; if(!(p == C[i] || (p + 1) % n == C[i]))return 0; } for(int i = n; i >= 1; i--) //a,b,? { if(A[i] >= n || B[i] >= n || C[i] < n) continue; p1 = (A[i] + B[i]) % n; p2 = (p1 + 1) % n; if(vis[p1] && vis[p2])return 0; } for(int i = n; i >= 1; i--) //a,?,c { if(A[i] >= n || B[i] < n || C[i] >= n) continue; p1 = (C[i] - A[i] + n) % n; p2 = (p1 - 1) % n; if(vis[p1] && vis[p2])return 0; } for(int i = n; i >= 1; i--) //?,b,c { if(A[i] < n || B[i] >= n || C[i] >= n) continue; p1 = (C[i] - B[i] + n) % n; p2 = (p1 - 1) % n; if(vis[p1] && vis[p2])return 0; } return 1; } bool dfs(int now) { if(!check1() || !check2())return 0; if(now > cnt) { print();return 1; } for(int i = n - 1; i >= 0; i--) { if(!vis[i]) { vis[i] = 1; keys[words[now] - 'A'] = i; change(A,words[now],i); change(B,words[now],i); change(C,words[now],i); if(dfs(now + 1))return 1; change(A,i,words[now]); change(B,i,words[now]); change(C,i,words[now]); vis[i] = 0; } } return 0; } int main() { scanf("%d",&n); scanf("%s%s%s",A+1,B+1,C+1); cnt = 0; for(int i = n; i >= 1; i--) { if(!vis[A[i] - 'A'])words[++cnt] = A[i],vis[A[i] - 'A'] = 1; if(!vis[B[i] - 'A'])words[++cnt] = B[i],vis[B[i] - 'A'] = 1; if(!vis[C[i] - 'A'])words[++cnt] = C[i],vis[C[i] - 'A'] = 1; } memset(vis,0,sizeof vis); dfs(1); return 0; }