zoukankan      html  css  js  c++  java
  • hdu3579 Hello Kiki(数论)

    用到中国剩余定理,然后用扩展欧几里得算法求解。

    这里有两个注意点,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
    ",A[0]);
            	continue;
            }
             printf("%d
    ",calcu(1));
    	}
    	return 0;
    }



  • 相关阅读:
    EasyUI——常见用法总结
    递归算法(转)
    1215整理
    jQuery Ajax 实例 全解析(转)
    EL表达式 (详解)
    JSTL 核心标签库 使用(转)
    JSTL标签用法 详解(转)
    JDBC连接Oracle数据库时出现的ORA-12505错误及解决办法
    java中的基本jdbc中mvc基本示例
    Hibernate的QBC检索方式
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3172246.html
Copyright © 2011-2022 走看看