user-0 提问: 求大神指教，化简程序，在500MS内输出即可

回复:
user: user-1
content: 学习学习，受教了！

user: user-2

user: user-3
content: 进来学习

user: user-4
content: 五人一列余2,个位怎么可以是1

user: user-5
content: 使用网易邮箱的撤销功能，对方是看不到的被撤销的邮件的，不过只能够撤销1小时之内的哦

user: user-6
content: 学习一下 HEHE

user: user-7
content: 5楼的思路表达得相当清晰。正确性的证明，额。。。其实这个问题就是中国余数定理啦。 我的建议也是在按照5楼的迭代思路迭代基础上有几个改进。 1，先理解迭代思路：对于A和B互素（A和B不必都是素数），余数分别是a和b，分别搜索合适的非负整数m和n， 使Am mod B = 1，Bn mod A = 1（这里m和n是必然存在的，不证明了），则 r = (Amb + Bna) mod AB为所求，将A和B合并成AB，余数对应变成了r进入下一次迭代。 2，从具体问题上考虑，应当首先获取全部输入后对余数相同的素数分别直接合并成最小公倍数(因为两两互素，所以就是乘积啦)，理论上有利于减少迭代次数。 3，从前面第1点可以看到搜索m和n是最影响性能的步骤。那么问题来了，怎样更快搜索到m和n？这是我的那20%部分啦。 由1知m和n只与A和B有关，与余数无关，且由同余法则可得，小于B的m必存在，小于n的A必存在，因此 Am + Bn ＜AB + BA = 2AB；另一方面，事实上，令a=b=1，则r=1，即(Am + Bn) mod AB = 1。因此 满足Am + Bn = AB + 1的m和n必然存在。m和n只需要搜索其中一个另一个可直接计算不必再次搜索。 设A>B，则m的最差搜索次数小于n的最差搜索次数。 所以，为了搜索m或n的次数最优化，对素数进行大小排序可能是有必要的。迭代应当从最大的开始，理由。。你懂的。

user: user-7
content: 5楼的思路表达得相当清晰。正确性的证明，额。。。其实这个问题就是中国余数定理啦。 我的建议也是在按照5楼的迭代思路迭代基础上有几个改进。 1，先理解迭代思路：对于A和B互素（A和B不必都是素数），余数分别是a和b，分别搜索合适的非负整数m和n， 使Am mod B = 1，Bn mod A = 1（这里m和n是必然存在的，不证明了），则 r = (Amb + Bna) mod AB为所求，将A和B合并成AB，余数对应变成了r进入下一次迭代。 2，从具体问题上考虑，应当首先获取全部输入后对余数相同的素数分别直接合并成最小公倍数(因为两两互素，所以就是乘积啦)，理论上有利于减少迭代次数。 3，从前面第1点可以看到搜索m和n是最影响性能的步骤。那么问题来了，怎样更快搜索到m和n？这是我的那20%部分啦。 由1知m和n只与A和B有关，与余数无关，且由同余法则可得，小于B的m必存在，小于n的A必存在，因此 Am + Bn ＜AB + BA = 2AB；另一方面，事实上，令a=b=1，则r=1，即(Am + Bn) mod AB = 1。因此 满足Am + Bn = AB + 1的m和n必然存在。m和n只需要搜索其中一个另一个可直接计算不必再次搜索。 设A>B，则m的最差搜索次数小于n的最差搜索次数。 所以，为了搜索m或n的次数最优化，对素数进行大小排序可能是有必要的。迭代应当从最大的开始，理由。。你懂的。

user: user-8
content: n := (d4*i + c4) mod a5;     if n = b5 then     begin

user: user-9
content: 另补充下，这类问题，在阶数不是比较高的情况下，弄明白整数规划后，用手工都能算出来的，先去看看《运筹学》中的整数规划吧

user: user-9
content: 1. 这是运筹学中典型的整数规划问题（参见清华大学出版社的《运筹学》）； 2. 这类问题，不建议直接用计算机程序直接求解； 3. 建议利用运筹学中的整数规划对算法进行优化后，再用计算机程序实现，这样计算量会小很多很多； 4. 如果可能的话，再在第3步实现的基础上，增加并发计算的可能性，以提高性能。

user: user-10
content: 中国剩余数定理解法#include <stdio.h> #include <assert.h> #include <string.h> #define DEBUG #ifdef DEBUG #include <time.h> #endif enum{LEN=32}; // a+=b void add(unsigned int*a,size_t *asz,const unsigned int*b,size_t bsz); // a*=b void mul(unsigned int*a,size_t *size,unsigned long long b); // a%=b void rem(unsigned int *a,size_t *asz,const unsigned int*b,size_t bsz); // ax+by=g -> return x unsigned long long exgcd(const unsigned int*a,size_t size,unsigned long long b); int main() {     unsigned long long mi[8],ai[8],result;     unsigned int Mi[8][LEN],M[LEN];     size_t i,j,Mi_size[8]={0},M_size=0; #ifdef DEBUG     clock_t tim; #endif     for(i=0;i<8;++i)         scanf("%llu",mi+i);     for(i=0;i<8;++i)         scanf("%llu",ai+i); #ifdef DEBUG     tim=clock(); #endif     for(i=0;i<8;++i)         mul(M,&M_size,mi[i]);     for(i=0;i<8;++i)         for(j=0;j<8;++j)             if(i!=j)                 mul(Mi[i],Mi_size+i,mi[j]);     for(i=0;i<8;++i)     {         unsigned long long x=exgcd(Mi[i],Mi_size[i],mi[i]);         mul(Mi[i],Mi_size+i,x);         mul(Mi[i],Mi_size+i,ai[i]);     }     for(i=1;i<8;++i)         add(Mi[0],Mi_size,Mi[i],Mi_size[i]);     rem(Mi[0],Mi_size,M,M_size);     assert(Mi_size[0]<=2);     switch(Mi_size[0])     {         case 0:result=0;break;         case 1:result=Mi[0][0];break;         case 2:result=*(unsigned long long*)Mi[0];break;     }     if(M_size<=2)     {         for(i=1;i<8;++i)             if(mi[0]<mi[i])                 mi[0]=mi[i];         if(result<mi[0])         {             unsigned long long MM=0;             switch(M_size)             {                 case 0:MM=0;break;                 case 1:MM=M[0];break;                 case 2:MM=*(unsigned long long*)M;break;             }             result+=MM;         }     }     printf("%llu\n",result); #ifdef DEBUG     printf("time:%gs\n",(double)(clock()-tim)/CLOCKS_PER_SEC); #endif     return 0; } void add(unsigned int*a,size_t *asz,const unsigned int*b,size_t bsz) {     unsigned int v[LEN]={0};     size_t vsz=0;     unsigned long long r=0;     while(vsz<*asz||vsz<bsz)     {         if(vsz<*asz)             r+=a[vsz];         if(vsz<bsz)             r+=b[vsz];         v[vsz++]=(unsigned int)r;         r>>=32;     }     if(r)         v[vsz++]=(unsigned int)r;     memcpy(a,v,sizeof v);     *asz=vsz;     assert(*asz<LEN); } void mul(unsigned int*a,size_t *size,unsigned long long b) {     unsigned long long r=0;     size_t i;     if(!*size)     {         *(unsigned long long*)a=b;         *size=b>>32?2:1;     }     else if(b>>32)     {         unsigned long long c=(unsigned int)b;         b>>=32;         for(i=0;i<*size;++i)         {             unsigned int t[3]={0};             *(unsigned long long*)t=a[i]*c+(r&-1U);             *(unsigned long long*)(t+1)+=a[i]*b+(r>>32);             a[i]=t[0];             r=*(unsigned long long*)(t+1);         }         if(r)         {             *(unsigned long long*)(a+*size)=r;             *size+=r>>32?2:1;         }     }     else     {         for(i=0;i<*size;++i)         {             r+=a[i]*b;             a[i]=(unsigned int)r;             r>>=32;         }         if(r)             a[(*size)++]=(unsigned int)r;     }     assert(*size<LEN); } void rem(unsigned int *a,size_t *asz,const unsigned int*b,size_t bsz) {     unsigned int r[LEN];     size_t rsz=0,l=*asz<<5,i;     while(l--)     {         if(!rsz)         {             if(a[l>>5]>>(l&31)&1)                 r[rsz++]=1;         }         else         {             i=rsz-1;             if(r[rsz-1]>>31)                 r[rsz++]=1;             while(i)             {                 r[i]=r[i]<<1|r[i-1]>>31;                 --i;             }             r[0]=(r[0]<<1)|((a[l>>5]>>(l&31))&1);         }         if(rsz>bsz)         {             for(i=bsz;i;--i)                *(unsigned long long*)(r+i-1)-=b[i-1];             while(rsz&&!r[rsz-1]) --rsz;         }         else if(rsz&&rsz==bsz)         {             for(i=rsz;i&&r[i-1]==b[i-1];--i);             if(!i||r[i-1]>b[i-1])             {                 r[rsz-1]-=b[bsz-1];                 for(i=rsz-1;i;--i)                     *(unsigned long long*)(r+i-1)-=b[i-1];                 while(rsz&&!r[rsz-1]) --rsz;             }         }     }     memcpy(a,r,sizeof r);     *asz=rsz;     assert(*asz<LEN); } unsigned long long exgcd(const unsigned int*a,size_t size,unsigned long long b) {     long long x[2]={0,1};     unsigned long long aa=b,bb=0,r;     if(1==size)         bb=a[0]%b;     else     {         unsigned int tmp[LEN];         size_t tsz=size;         memcpy(tmp,a,sizeof tmp);         rem(tmp,&tsz,(unsigned int*)&b,b>>32?2:1);         assert(tsz<=2);         switch(tsz)         {             case 0:bb=0;break;             case 1:bb=*tmp;break;             case 2:bb=*(unsigned long long*)tmp;break;         }     }     do     {         long long t=x[0];x[0]=x[1];x[1]=t-aa/bb*x[0];         r=aa%bb;aa=bb;bb=r;     }while(bb);     if(x[0]>=0)         return (unsigned long long)x[0];     else         return (unsigned long long)((long long)b+x[0]); } 附测试数据和结果 2 3 5 7 11 13 17 19 1 1 1 1 1 1 1 1 9699691 time:5.7e-05s  9223372036854775399 9223372036854775417 9223372036854775421 9223372036854775433 9223372036854775507 9223372036854775549 9223372036854775643 9223372036854775783 408 390 386 374 300 258 164 24 9223372036854775807 time:0.000285s 4294967111 4294967143 4294967161 4294967189 4294967197 4294967231 4294967279 4294967291 2147500667 2147495275 2147492692 2147489318 2147488498 2147485727 2147483783 2147483657 9223372036854775807 time:0.000137s  4294967111 4294967143 4294967161 4294967189 4294967197 4294967231 4294967279 4294967291 400879708 76365989 2309746472 1488927345 2481541213 2405183635 4065902492 1259857083 8690466096661279830 time:0.000127s

user: user-11
content: 7+3m=7+5n,             3m=5n,  m肯定有5的因子， n肯定有3的因子。

user: user-12

user: user-13
content: 网上搜了一下中国剩余数定理，数学原理告诉我们定域内解是唯一的。 至少有6种解法，其中至少三种符合楼主的要求。 我的这种是逐级求解法，计算时间还是长了，有不用循环，直奔答案的解法。

user: user-13
content: d2 := a1*a2; n := (d2*i + c2) mod a3; 为什么要用前面数的最小公倍数做基数，为什么一个基数倍域范围内只有只一个解，这里我用的是经验公式，数学原理也不清楚。

user: user-13
content: 07年的明基笔记本跑不出毫秒级时差   StartTime:=GetTickCount;   a1:=2; a2:=3; a3:=5; a4:=7; a5:=11; a6:=13; a7:=17; a8:=19;   b1:=1; b2:=1; b3:=1; b4:=1;  b5:=1;  b6:=1; b7:=1;  b8:=1;   for i := 1 to a2 do   begin     n := (a1*i + b1) mod a2;     if n = b2 then     begin       c2 := a1*i + b1;       d2 := a1*a2;       break;     end;   end;   //i = 3  c2 = 7   for i := 1 to a3 do   begin     n := (d2*i + c2) mod a3;     if n = b3 then     begin       c3 := d2*i + c2;       d3 := d2*a3;       break;     end;   end;   //i = 4 c3 = 31   for i := 1 to a4 do   begin     n := (d3*i + c3) mod a4;     if n = b4 then     begin       c4 := d3*i + c3;       d4 := d3*a4;       break;     end;   end;   //i = 6 c4=211   for i := 1 to a5 do   begin     n := (d4*i + c4) mod a5;     if n = b5 then     begin       c5 := d4*i + c4;       d5 := d4*a5;       break;     end;   end;   //i = 10 c5=2311   for i := 1 to a6 do   begin     n := (d5*i + c5) mod a6;     if n = b6 then     begin       c6 := d5*i + c5;       d6 := d5*a6;       break;     end;   end;   //i = 12 c6=30031   for i := 1 to a7 do   begin     n := (d6*i + c6) mod a7;     if n = b7 then     begin       c7 := d6*i + c6;       d7 := d6*a7;       break;     end;   end;   //i = 16 c7=510511   for i := 1 to a8 do   begin     n := (d7*i + c7) mod a8;     if n = b8 then     begin       c8 := d7*i + c7;       d8 := d7*a8;       break;     end;   end;   //i = 18; c8=9699691   EndTime:=GetTickCount;

user: user-13
content: 求最小值，共循环57次，算法分解，一目了然   a1:=3; a2:=5; a3:=7; a4:=13; a5:=17; a6:=19; a7:=23; a8:=29;   b1:=1; b2:=2; b3:=4; b4:=6;  b5:=2;  b6:=10; b7:=1;  b8:=11;   for i := 1 to a2 do   begin     n := (a1*i + b1) mod a2;     if n = b2 then     begin       c2 := a1*i + b1;       d2 := a1*a2;       break;     end;   end;   //i = 2  c2 = 7   for i := 1 to a3 do   begin     n := (d2*i + c2) mod a3;     if n = b3 then     begin       c3 := d2*i + c2;       d3 := d2*a3;       break;     end;   end;   //i = 4 c3 = 67   for i := 1 to a4 do   begin     n := (d3*i + c3) mod a4;     if n = b4 then     begin       c4 := d3*i + c3;       d4 := d3*a4;       break;     end;   end;   //i = 4 c4=487   for i := 1 to a5 do   begin     n := (d4*i + c4) mod a5;     if n = b5 then     begin       c5 := d4*i + c4;       d5 := d4*a5;       break;     end;   end;   //i = 5 c5=7312   for i := 1 to a6 do   begin     n := (d5*i + c5) mod a6;     if n = b6 then     begin       c6 := d5*i + c5;       d6 := d5*a6;       break;     end;   end;   //i = 18 c6=425002   for i := 1 to a7 do   begin     n := (d6*i + c6) mod a7;     if n = b7 then     begin       c7 := d6*i + c6;       d7 := d6*a7;       break;     end;   end;   //i = 2 c7=1306792   for i := 1 to a8 do   begin     n := (d7*i + c7) mod a8;     if n = b8 then     begin       c8 := d7*i + c7;       d8 := d7*a8;       break;     end;   end;   //i = 22; c8=224399662

user: user-13
content: for(k=mn/(a[i]-1),s=0,ab=0;ab<=mn;k++)范围太大 15X+7=7Y+4<15*7 过滤掉了绝大部分的不可能数据

user: user-13
content: 我是逐位求，你得是直接来八个，这样逐个计算太浪费。