Description
Input
Output
Sample Input
2 1 2 3 0 0
Sample Output
5
题意:N%M[i]=M[i]-a; 另A[i]=M[i]-a; N%M[i]=A[i];
变形就是中国剩余定理<不互质版>:不理解可以看:http://blog.csdn.net/u010579068/article/details/45422941
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1788
转载请注明出处:http://blog.csdn.net/u010579068
我用这篇的代码改的。
#include<stdio.h> #define LL __int64 void exgcd(LL a,LL b,LL& d,LL& x,LL& y) { if(!b){d=a;x=1;y=0;} else { exgcd(b,a%b,d,y,x); y-=x*(a/b); } } LL gcd(LL a,LL b) { if(!b){return a;} gcd(b,a%b); } LL M[55],A[55]; LL China(int r) { LL dm,i,a,b,x,y,d; LL c,c1,c2; a=M[0]; c1=A[0]; for(i=1; i<r; i++) { b=M[i]; c2=A[i]; exgcd(a,b,d,x,y); c=c2-c1; if(c%d) return -1;//c一定是d的倍数,如果不是,则,肯定无解 dm=b/d; x=((x*(c/d))%dm+dm)%dm;//保证x为最小正数//c/dm是余数,系数扩大余数被 c1=a*x+c1; a=a*dm; } if(c1==0)//余数为0,说明M[]是等比数列。且余数都为0 { c1=1; for(i=0;i<r;i++) c1=c1*M[i]/gcd(c1,M[i]); } return c1; } int main() { int I,r; while(scanf("%d%d",&I,&r),(I+r)) { for(int i=0;i<I;i++) { scanf("%I64d",&M[i]); A[i]=M[i]-r; } LL ans=China(I); printf("%I64d\n",ans); } return 0; }