标签:
如果直接枚举的话,枚举量为k1 * k2 *...* kc
根据枚举量的不同,有两种解法。
上面两种方法都要注意所找到的解为正整数。
1 typedef long long LL; 2 3 void gcd(LL a, LL b, LL& d, LL& x, LL& y) 4 { 5 if(!b) { d = a; x = 1; y = 0; } 6 else { gcd(b, a%b, d, y, x); y -= x*(a/b); } 7 } 8 9 LL china(int n, int* a, int* m) 10 { 11 LL M = 1, d, y, x = 0; 12 for(int i = 0; i < n; i++) M *= m[i]; 13 for(int i = 0; i < n; i++) 14 { 15 LL w = M / m[i]; 16 gcd(m[i], w, d, d, y); 17 x = (x + y*w*a[i]) % M; 18 } 19 return (x+M)%M; 20 } 21 22 #include <cstdio> 23 #include <vector> 24 #include <set> 25 #include <algorithm> 26 #include <cstring> 27 using namespace std; 28 29 const int maxc = 9; 30 const int maxk = 100; 31 const int LIMIT = 10000; 32 int C, S; 33 int bestc; 34 int X[maxc], Y[maxc][maxk], k[maxc]; 35 set<int> values[maxc]; 36 37 void solve_enum() 38 { 39 for(int c = 0; c < C; c++) if(c != bestc) 40 { 41 values[c].clear(); 42 for(int i = 0; i < k[c]; i++) 43 values[c].insert(Y[c][i]); 44 } 45 46 for(int t = 0; S != 0; t++) 47 { 48 for(int i = 0; i < k[bestc]; i++) 49 { 50 LL n = (LL)t * X[bestc] + Y[bestc][i];//枚举解 51 if(n == 0) continue; 52 bool ok = true; 53 for(int c = 0; c < C; c++) if(c != bestc)//判断是否符合要求 54 if(!values[c].count(n % X[c])) { ok = false; break; } 55 if(ok) { printf("%lld\n", n); if(--S == 0) { break; } } 56 } 57 } 58 } 59 60 int a[maxc]; 61 vector<LL> sol; 62 63 void dfs(int d) 64 { 65 if(d == C) sol.push_back(china(C, a, X)); 66 else for(int i = 0; i < k[d]; i++) 67 { 68 a[d] = Y[d][i]; 69 dfs(d + 1); 70 } 71 } 72 73 void solve_china() 74 { 75 sol.clear(); 76 dfs(0); 77 sort(sol.begin(), sol.end()); 78 79 LL M = 1; 80 for(int i = 0; i < C; i++) M *= X[i]; 81 82 for(int i = 0; S != 0; i++) 83 { 84 for(int j = 0; j < sol.size(); j++) 85 { 86 LL n = M * i + sol[j]; 87 if(n == 0) continue; 88 printf("%lld\n", n); 89 if(--S == 0) break; 90 } 91 } 92 } 93 94 int main() 95 { 96 freopen("in.txt", "r", stdin); 97 98 while(scanf("%d%d", &C, &S) == 2 && C && S) 99 { 100 bestc = 0; 101 int tot = 1; 102 for(int c = 0; c < C; c++) 103 { 104 scanf("%d%d", &X[c], &k[c]); 105 tot *= k[c]; 106 if(k[c] * X[bestc] < k[bestc] * X[c]) bestc = c; 107 for(int i = 0; i < k[c]; i++) 108 scanf("%d", &Y[c][i]); 109 sort(Y[c], Y[c] + k[c]); 110 } 111 112 if(tot > LIMIT) solve_enum(); 113 else solve_china(); 114 printf("\n"); 115 } 116 117 return 0; 118 }
UVa 11754 (中国剩余定理 枚举) Code Feat
标签:
原文地址:http://www.cnblogs.com/AOQNRMGYXLMV/p/4322196.html