zoukankan      html  css  js  c++  java
  • UVA 11754 Code Feat (枚举,中国剩余定理)

    转载请注明出处: http://www.cnblogs.com/fraud/           ——by fraud

    C

    Code Feat

     

    The government hackers at CTU (Counter-Terrorist Unit) have learned some things about the code, but they still haven't quite solved it.They know it's a single, strictly positive, integer.  They also know several clues of the form "when divided by X, the remainder is one of {Y1, Y2, Y3, ...,Yk}".There are multiple solutions to these clues, but the code is likely to be one of the smallest ones.  So they'd like you to print out the first few solutions, in increasing order.

    The world is counting on you!

    Input

    Input consists of several test cases.  Each test case starts with a line containing C, the number of clues (1 <= C <= 9), and S, the number of desired solutions (1 <= S <= 10).  The next C lines each start with two integers X (2 <= X) and k (1 <= k <= 100), followed by the k distinct integers Y1, Y2, ...,Yk (0 <= Y1, Y2, ..., Yk < X).

    You may assume that the Xs in each test case are pairwise relatively prime (ie, they have no common factor except 1).  Also, the product of the Xs will fit into a 32-bit integer.

    The last test case is followed by a line containing two zeros.

    Output

    For each test case, output S lines containing the S smallest positive solutions to the clues, in increasing order.

    Print a blank line after the output for each test case.

    Sample Input                              

    Sample Output

     

    3 2

    2 1 1

    5 2 0 3

    3 2 1 2

    0 0

    5

    13

     

    Problem Setter: Derek Kisman, Special Thanks: SameeZahur

    当所有k的乘积较小时,直接枚举出所有的情况,然后用中国剩余定理(CRT)即可求解;

    当所有k的乘积较大时,直接枚举所有值,判断是否符合即可。注意k/x越小越好,这样t*x+yi足够大,很快就能找到

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <set>
      4 #include <cstring>
      5 #include <vector>
      6 #include <algorithm>
      7 using namespace std;
      8 long long X[11],K[11],Y[11][110];
      9 vector<long long >vec;
     10 set<int>val[11];
     11 long long c,s;
     12 long long mod;
     13 int minn=0;
     14 typedef long long ll;
     15 void ext_gcd(ll a,ll b,ll &d,ll &x,ll &y)
     16 {
     17     if(!b){d=a;x=1;y=0;}
     18     else
     19     {
     20         ext_gcd(b,a%b,d,y,x);
     21         y-=x*(a/b);
     22     }
     23 }
     24 ll a[11];
     25 ll CRT()
     26 {
     27     ll d,x,y,ret=0;
     28     ll temp;
     29     for(int i=0;i<c;i++)
     30     {
     31         temp=mod/X[i];
     32         ext_gcd(X[i],temp,d,x,y);
     33         ret=(ret+y*temp*a[i])%mod;
     34     }
     35     return (ret+mod)%mod;
     36 }
     37 void dfs(int d)
     38 {
     39     if(d==c)vec.push_back(CRT());
     40     else
     41     {
     42         for(int i=0;i<K[d];i++)
     43         {
     44             a[d]=Y[d][i];
     45             dfs(d+1);
     46         }
     47     }
     48 }
     49 void solve1()
     50 {
     51     vec.clear();
     52     dfs(0);
     53     sort(vec.begin(),vec.end());
     54     int size=vec.size();
     55     int num=0;
     56     for(int i=0;;i++)
     57     {
     58         for(int j=0;j<size;j++)
     59         {
     60             ll ans=mod*i+vec[j];
     61             if(ans>0)
     62             {
     63                 printf("%lld
    ",ans);
     64                 num++;
     65                 if(num==s)return ;
     66             }
     67         }
     68     }
     69 }
     70 void solve2()
     71 {
     72     for(int i=0;i<c;i++)
     73     {
     74         if(i!=minn)
     75         {
     76             val[i].clear();
     77             for(int j=0;j<K[i];j++)
     78             {
     79                 val[i].insert(Y[i][j]);
     80             }
     81         }
     82     }
     83     ll ans=0;
     84     bool ok=1;
     85     int num=0;
     86     for(int i=0;;i++)
     87     {
     88         for(int j=0;j<K[minn];j++)
     89         {
     90             ans=X[minn]*i+Y[minn][j];
     91             if(ans<=0)continue;
     92             ok =1;
     93             for(int k=0;k<c;k++)
     94             {
     95                 if(k!=minn&&!val[k].count(ans%X[k]))
     96                 {
     97                     ok=0;
     98                     break;
     99                 }
    100             }
    101             if(ok)
    102             {
    103                 printf("%lld
    ",ans);
    104                 num++;
    105                 if(num==s)return;
    106             }
    107         }
    108     }
    109 }
    110 int main()
    111 {
    112     while(scanf("%lld%lld",&c,&s)==2&&(c||s))
    113     {
    114         if(c==0&&s==0)break;
    115         mod=1;
    116         minn=0;
    117         long long k=1;
    118         for(int i=0;i<c;i++)
    119         {
    120             scanf("%lld%lld",&X[i],&K[i]);
    121             mod*=X[i];
    122             k*=K[i];
    123             for(int j=0;j<K[i];j++)
    124             {
    125                 scanf("%lld",&Y[i][j]);
    126             }
    127             sort(Y[i],Y[i]+K[i]);
    128             if(K[i]*X[minn]>K[minn]*X[i])minn=i;
    129         }
    130         if(k>10000)solve2();
    131         else solve1();
    132         printf("
    ");
    133 
    134     }
    135     return 0;
    136 }
    View Code
  • 相关阅读:
    微分中值定理和泰勒展开
    Burnside引理与Polya定理
    递推关系和母函数
    cogs 1361. 树 线段树
    cogs 247. 售票系统 线段树
    cogs 176. [USACO Feb07] 奶牛聚会 dijkstra
    cogs 1672. [SPOJ 375] 难存的情缘 树链剖分套线段树 易错! 全博客园最长最详细的题解
    cogs 886. [USACO 4.2] 完美的牛栏 二分图 匈牙利算法
    cogs 1254. 最难的任务 Dijkstra + 重边处理
    cogs 364. [HDU 1548] 奇怪的电梯 Dijkstra
  • 原文地址:https://www.cnblogs.com/fraud/p/4127338.html
Copyright © 2011-2022 走看看