• uva 11754 Code Feat (中国剩余定理)


    UVA 11754

      一道中国剩余定理加上搜索的题目。分两种情况来考虑,当组合总数比较大的时候,就选择枚举的方式,组合总数的时候比较小时就选择搜索然后用中国剩余定理求出得数。

    代码如下:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <cmath>
      6 #include <set>
      7 
      8 using namespace std;
      9 
     10 typedef long long LL;
     11 
     12 const int N = 11;
     13 const int UB = 11111;
     14 int X[N], C, S;
     15 LL ans[UB], R[N];
     16 set<int> Y[N];
     17 #define ITOR iterator
     18 
     19 template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a;}
     20 void gcd(LL a, LL b, LL &d, LL &x, LL & y) {
     21     if (b) { gcd(b, a % b, d, y, x); y -= a / b * x;}
     22     else d = a, x = 1, y = 0;
     23 }
     24 LL lcm(LL a, LL b) { return a / gcd(a, b) * b;}
     25 
     26 LL cal() {
     27     LL a = X[0], r = R[0] % a, d, x, y, tmp;
     28     for (int i = 1; i < C; i++) {
     29         gcd(a, X[i], d, x, y);
     30         if ((R[i] - r) % d) return -1;
     31         tmp = a * x * ((R[i] - r) / d) + r;
     32         a = lcm(a, X[i]);
     33         r = (tmp % a + a) % a;
     34     }
     35     return r ? r : a + r;
     36 }
     37 
     38 void dfs(int p) {
     39     if (p == C) {
     40         LL tmp = cal();
     41         if (~tmp) ans[++ans[0]] = tmp;
     42         return ;
     43     }
     44     set<int>::ITOR si;
     45     for (si = Y[p].begin(); si != Y[p].end(); si++) {
     46         R[p] = *si;
     47         dfs(p + 1);
     48     }
     49 }
     50 
     51 void workdfs() {
     52     LL LCM = 1;
     53     for (int i = 0; i < C; i++) LCM = lcm(LCM, X[i]);
     54     ans[0] = 0;
     55     dfs(0);
     56     sort(ans + 1, ans + ans[0] + 1);
     57     ans[0] = (int) (unique(ans + 1, ans + ans[0] + 1) - ans - 1);
     58     int mk = ans[0];
     59     while (ans[0] < S) ans[ans[0] + 1] = ans[ans[0] + 1 - mk] + LCM, ans[0]++;
     60 }
     61 
     62 bool test(LL x) {
     63     for (int i = 0; i < C; i++) {
     64         if (Y[i].find(x % X[i]) == Y[i].end()) return false;
     65     }
     66     return true;
     67 }
     68 
     69 void workenum(int mk) {
     70     set<int>::ITOR si;
     71     ans[0] = 0;
     72     for (int t = 0; ans[0] < S; t++) {
     73         for (si = Y[mk].begin(); si != Y[mk].end() && ans[0] < S; si++) {
     74             LL cur = (LL) t * X[mk] + *si;
     75             if ( cur && test(cur)) ans[++ans[0]] = cur;
     76         }
     77     }
     78 }
     79 
     80 int main() {
     81     while (~scanf("%d%d", &C, &S) && (C || S)) {
     82         int mk = 0, tt = 1, y, k; 
     83         bool enm = false;
     84         for (int i = 0; i < C; i++) {
     85             scanf("%d%d", X + i, &k);
     86             Y[i].clear();
     87             for (int j = 1; j <= k; j++) {
     88                 scanf("%d", &y);
     89                 Y[i].insert(y);
     90             }
     91             if (k * X[i] < k * X[mk]) mk = i;
     92             tt *= k;
     93             if (tt > UB) enm = true;
     94         }
     95         if (enm) workenum(mk);
     96         else workdfs();
     97         ans[0] = min(ans[0], (LL) S);
     98         for (int i = 1; i <= ans[0]; i++) printf("%lld
    ", ans[i]);
     99         puts("");
    100     }
    101     return 0;
    102 }
    View Code

    ——written by Lyon

  • 相关阅读:
    生成器
    迭代器
    装饰器
    Maven工具学习(六)----Maven依赖的版本锁定与版本常量
    SpringBoot学习记录之整合JSP
    SpringBoot学习记录之入门篇
    【k8s】ep-addresses
    【k8s】ep-metadata
    【k8s】Endpoints
    【k8s】cj-suspend
  • 原文地址:https://www.cnblogs.com/LyonLys/p/uva_11754_Lyon.html
Copyright © 2020-2023  润新知