【NOIP 2004】 虫食算
【题目链接】
https://www.luogu.org/problemnew/show/P1092
【算法】
搜索 + 剪枝
直接搜索显然会超时,考虑剪枝
1 : 优化搜索顺序
2 : 假设我们已经确定了一组(Ai,Bi,Ci),那么,如果(Ai + Bi) mod n 和(Ai + Bi + 1) mod n都不等于Ci,可以剪枝
【代码】
#include<bits/stdc++.h> using namespace std; int i,n,len; int a[30],ord[30]; char A[30],B[30],C[30]; bool used[30],vis[30]; bool solved; inline bool ok() { int i; for (i = n; i >= 1; i--) { if (a[A[i]-'A'+1] == -1) continue; if (a[B[i]-'A'+1] == -1) continue; if (a[C[i]-'A'+1] == -1) continue; if ((a[A[i]-'A'+1] + a[B[i]-'A'+1]) % n == a[C[i]-'A'+1]) continue; if ((a[A[i]-'A'+1] + a[B[i]-'A'+1] + 1) % n == a[C[i]-'A'+1]) continue; return false; } return true; } inline void print() { int i; for (i = 1; i <= n; i++) printf("%d ",a[i]); printf("\n"); } inline bool check() { int t,b = 0; for (i = n; i >= 1; i--) { t = (a[A[i]-'A'+1] + a[B[i]-'A'+1] + b) % n; if (a[A[i]-'A'+1] + a[B[i]-'A'+1] + b >= n) b = 1; else b = 0; if (a[C[i]-'A'+1] == t) continue; else return false; } if (b) return false; else return true; } inline void dfs(int dep) { int i; if (dep > n) { if (check()) { solved = true; print(); } return; } if (!ok()) return; for (i = n - 1; i >= 0; i--) { if (!used[i]) { a[ord[dep]] = i; used[i] = true; dfs(dep+1); if (solved) return; used[i] = false; a[ord[dep]] = -1; } } } int main() { memset(a,255,sizeof(a)); scanf("%d%s%s%s",&n,A+1,B+1,C+1); for (i = n; i >= 1; i--) { if (!vis[A[i]-'A'+1]) { ord[++len] = A[i] - 'A' + 1; vis[A[i]-'A'+1] = true; } if (!vis[B[i]-'A'+1]) { ord[++len] = B[i] - 'A' + 1; vis[B[i]-'A'+1] = true; } if (!vis[C[i]-'A'+1]) { ord[++len] = C[i] - 'A' + 1; vis[C[i]-'A'+1] = true; } } dfs(1); return 0; }