uva 11754 Code Feat 中国剩余定理

题目:https://uva.onlinejudge.org/external/117/11754.pdf


中国剩余定理和拓展欧几里德感觉还没弄清楚,只能套模板。

这题这是照着书上的代码写的:

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<cctype>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI 3.1415926535897932384626
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n)  for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n)  for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n)  for(int i=(n) ;i>=0 ;i--)
#define  lson   num<<1,le,mid
#define rson    num<<1|1,mid+1,ri
#define MID   int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk    make_pair
#define _f     first
#define _s     second

using namespace std;
//const int INF=    ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int INF =0x3f3f3f3f;
const int maxc=  9  ;
const int maxk= 100;
const int LIMIT=10000;
set<int >value[maxc];
int C,X[maxc],k[maxc];
int Y[maxc][maxk];
int S;


//const int maxm=    ;
//by yskysker123


void Work(int bestc)
{
    for(int i=0;i<C;i++)
    {
        if(i==bestc)  continue;
        value[i].clear();//掉了
        for(int j=0;j<k[i];j++)
        {
            value[i].insert(Y[i][j]);
        }
    }
    for(int t=0 ;S ;t++ )
    {
        for(int j=0;j<k[bestc];j++)
        {
             ll n=(ll)t*X[bestc]+Y[bestc][j];//
             if(!n) continue ;//n不能为0
             bool ok=true;
             for(int i=0;i<C;i++)
             {
                 if(i==bestc)  continue;
                 if(!value[i].count(n%X[i]))
                 {
                     ok=false;
                     break;
                 }

             }
            if(ok) {printf("%lld\n",n);if(!(--S))  break;   }
        }

    }

}

vector<ll>  sol;
int a[maxc];

void gcd(ll a, ll b, ll d, ll& x, ll& y) {
  if(!b){ d = a; x = 1; y = 0; }
  else{ gcd(b, a%b, d, y, x); y -= x*(a/b); }
}

ll China(int n,int *a,int *m)//方程个数,余数,模m
{
    ll M=1,d,y,x=0;
    for(int i=0;i<n;i++)  M*=m[i];
    for(int i=0;i<n;i++)
    {
        ll w=M/m[i];
        gcd(m[i] ,w,1,d,y);
        x=(x+w*y*a[i])%M;
    }
    return (x+M)%M;
}



void dfs(int step)
{
    if(step==C)
        {sol.push_back(China( C ,a,X)) ;return;}//  ,余数(数组),模X(数组)

    for(int i=0;i<k[step];i++)
    {
        a[step]=Y[step][i];
        dfs(step+1);
    }

}


void Solve_China()
{
    sol.clear();
    dfs(0);
    ll M=1;
    for(int i=0;i<C;i++)
        M*=X[i];
    sort(sol.begin(),sol.end());
    for(int t=0;S;t++)
    {
        for(int i=0;i<sol.size();i++)
        {
           ll n=t*M+sol[i];
           if(!n)  continue;
           printf("%lld\n",n);
           if(  !(--S ) )  break;

        }
    }


}

int main()
{
   while(scanf("%d%d",&C,&S)==2&&(C||S))
   {
       ll tot=1;int bestc=0;
       for(int i=0;i<C;i++)
       {
           scanf("%d%d",&X[i],&k[i]);
           tot*=k[i];
           for(int j=0;j<k[i];j++)
           {
               scanf("%d",&Y[i][j]);
           }
           if( X[bestc]*k[i]<k[bestc]*X[i] )  bestc=i;

           sort(Y[i],Y[i]+k[i]);//掉了,不能保证最小
       }
       if(tot>LIMIT)  Work(bestc);
       else Solve_China();
       putchar('\n');

   }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值