uva 11754 Code Feat

题目大意:求一个数N,给出C和S,表示有C个条件,每个条件有X 和 k,然后是该个条件的k个yi,即NmodX=yj,输出满足的最小的S个N,要求正整数。

解题思路:tot为所有的k的乘积,也就是可以作为一组完整限定条件的可能数.当个tot较小可以用中国剩余定理处理,但是如果tot太大的话,可以通过枚举N来判断,找到一组k/X最小的做为枚举基准,然后判断即可,t*X+Y[i](t=0,1,2...).

  1 #include <iostream>
  2 #include <cstdio>
  3 #include<cstdlib>
  4 #include<cctype>
  5 #include<cstring>
  6 #include<vector>
  7 #include<cassert>
  8 #include<set>
  9 #include<algorithm>
 10 #define LL long long
 11 using namespace std;
 12 
 13 // 即使a, b在int范围内,x和y有可能超出int范围
 14 void gcd(LL a, LL b, LL& d, LL& x, LL& y)
 15 {
 16     if(!b)
 17     {
 18         d = a;
 19         x = 1;
 20         y = 0;
 21     }
 22     else
 23     {
 24         gcd(b, a%b, d, y, x);
 25         y -= x*(a/b);
 26     }
 27 }
 28 
 29 // n个方程:x=a[i](mod m[i]) (0<=i<n)
 30 LL china(int n, int* a, int *m)
 31 {
 32     LL M = 1, d, y, x = 0;
 33     for(int i = 0; i < n; i++) M *= m[i];
 34     for(int i = 0; i < n; i++)
 35     {
 36         LL w = M / m[i];
 37         gcd(m[i], w, d, d, y);
 38         x = (x + y*w*a[i]) % M;
 39     }
 40     return (x+M)%M;
 41 }
 42 
 43 const int maxc = 9;
 44 const int maxk = 100;
 45 const int LIMIT = 10000;
 46 int C;
 47 int X[maxk],k[maxc];
 48 int Y[maxc][maxk];
 49 set<int>values[maxc];
 50 
 51 void solve_enum(int S,int bc)
 52 {
 53     for(int c=0; c<C; c++)
 54         if(c!=bc)
 55         {
 56             values[c].clear();
 57             for(int i=0; i<k[c]; i++)
 58             {
 59                 values[c].insert(Y[c][i]);
 60             }
 61         }
 62     for(int t=0; S!=0; t++)
 63     {
 64         for(int i=0; i<k[bc]; i++)
 65         {
 66             LL n=X[bc]*t+Y[bc][i];
 67             if(n==0)
 68                 continue;
 69             bool ok=true;
 70             for(int c=0; c<C; c++)
 71             {
 72                 if(c!=bc)
 73                 {
 74                     if(!values[c].count(n%X[c]))
 75                     {
 76                         ok=false;
 77                         break;
 78                     }
 79                 }
 80             }
 81             if(ok)
 82             {
 83                 printf("%lld\n",n);
 84                 if(--S==0)
 85                     break;
 86             }
 87         }
 88     }
 89 }
 90 int a[maxc];
 91 vector<LL>sol;
 92 void dfs(int dep)
 93 {
 94     if(dep==C)
 95         sol.push_back(china(C,a,X));
 96     for(int i=0;i<k[dep];i++)
 97     {
 98         a[dep]=Y[dep][i];
 99         dfs(dep+1);
100     }
101 }
102 
103 void solve_china(int S)
104 {
105     sol.clear();
106     dfs(0);
107     sort(sol.begin(),sol.end());
108     LL M=1;
109     for(int i=0;i<C;i++)
110         M*=X[i];
111     for(int i=0;S!=0;i++)
112     {
113         for(int j=0;j<sol.size();j++)
114         {
115             LL n=M*i+sol[j];
116             if(n>0)
117             {
118                 printf("%lld\n",n);
119                 if(--S==0)
120                     break;
121             }
122         }
123 
124     }
125 }
126 int main()
127 {
128     int S;
129     while(scanf("%d%d",&C,&S)==2&&C)
130     {
131         LL tot=1;
132         int bestc=0;
133         for(int c=0; c<C; c++)
134         {
135             scanf("%d%d",&X[c],&k[c]);
136             tot*=k[c];
137             for(int i=0; i<k[c]; i++)
138             {
139                 scanf("%d",&Y[c][i]);
140             }
141             sort(Y[c],Y[c]+k[c]);
142             if(k[c]*X[bestc]<k[bestc]*X[C])
143                 bestc=c;
144         }
145         if(tot>LIMIT)
146             solve_enum(S,bestc);
147         else
148             solve_china(S);
149         printf("\n");
150     }
151     return 0;
152 }
View Code

 

posted @ 2015-10-31 16:12  yyblues  阅读(438)  评论(0编辑  收藏  举报