hdu3579 Hello Kiki(数论)
2013-07-03 22:32
148 查看
用到中国剩余定理,然后用扩展欧几里得算法求解。
这里有两个注意点,1、硬币数量不能为0或者负数
2、每个group数量有可能大于50,样例中就有
这里有两个注意点,1、硬币数量不能为0或者负数
2、每个group数量有可能大于50,样例中就有
#include<stdio.h> #include<math.h> #include<stdlib.h> int M[10],A[10],n; int extEuclid(int p,int q,int &x,int &y)//扩展欧几里得算法 { int d,tmp; if(q==0){x=1;y=0;return p;} d=extEuclid(q,p%q,x,y); tmp=x;x=y;y=tmp-p/q*y; return d;//返回最大公约数 } int calcu(int cur) { int x,y,g,t; int a1=M[cur-1],a2=M[cur]; int b1=A[cur-1],b2=A[cur]; g=extEuclid(a1,a2,x,y); int s=b2-b1; if(s%g) return -1; else { t=a2/g; x=x*s/g;//这个一定要放在“x=(x%t+t)%t”前面,否则就wa了 x=(x%t+t)%t;//求出在0~t之间的一个解。这一步必须有,否则就wa,因为爆int了,可改成long long,改过后也可以ac a2=a1*a2/g; s=((a1*x+b1)%a2+a2)%a2; A[cur]=s; M[cur]=a2; if(cur==n-1) { if(s==0) return M[cur]; else return A[cur]; } else return calcu(cur+1); } } int main() { int i,j,k,t; scanf("%d",&t); for(k=1;k<=t;k++) { scanf("%d",&n); for(i=0;i<n;i++) scanf("%d",&M[i]); for(i=0;i<n;i++) scanf("%d",&A[i]); printf("Case %d: ",k); if(n==1) { if(A[0]==0) A[0]=M[0]; printf("%d\n",A[0]); continue; } printf("%d\n",calcu(1)); } return 0; }
相关文章推荐
- 【数论】【扩展欧几里得】hdu3579 Hello Kiki
- hdu3579 Hello Kiki(数论)
- HDU3579 Hello Kiki 解线性同余方程的应用
- Hello Kiki(hdu3579线性同与方程)
- HDU3579 Hello Kiki【一元线性同余方程组】
- HDU3579 Hello Kiki(CRT非互质)
- 【hdu3579-Hello Kiki】拓展欧几里得-同余方程组
- 数论
- 【Light-oj】-1282 - Leading and Trailing(数论,快速幂,log,好)
- HIHO #1297 : 数论四·扩展欧几里德
- 数论回顾与扩展
- 数论 快速矩阵幂 POJ 3070 Fibonacci
- 基础数论-反素数 ural1748
- UVa 1645 Count (递推,数论)
- 51Nod 1073 - 约瑟夫环(数论)
- 约瑟夫的数论问题
- Codeforces 716C[数论][构造]
- Gym 100512F Funny Game (博弈+数论)
- hdu3579(中国剩余问题经典)
- 数论复习之中国剩余定理