程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> Hello Kiki&&http://acm.hdu.edu.cn/showproble

Hello Kiki&&http://acm.hdu.edu.cn/showproble

編輯:關於PHP編程

Problem Description
One day I was shopping in the supermarket. There was a cashier counting coins seriously when a little kid running and singing "門前大橋下游過一群鴨,快來快來 數一數,二四六七八". And then the cashier put the counted coins back morosely and count again...
Hello Kiki is such a lovely girl that she loves doing counting in a different way. For example, when she is counting X coins, she count them N times. Each time she divide the coins into several same sized groups and write down the group size Mi and the number of the remaining coins Ai on her note.
One day Kiki's father found her note and he wanted to know how much coins Kiki was counting.

Input
The first line is T indicating the number of test cases.
Each case contains N on the first line, Mi(1 <= i <= N) on the second line, and corresponding Ai(1 <= i <= N) on the third line.
All numbers in the input and output are integers.
1 <= T <= 100, 1 <= N <= 6, 1 <= Mi <= 50, 0 <= Ai < Mi

Output
For each case output the least positive integer X which Kiki was counting in the sample output format. If there is no solution then output -1.

Sample Input
2
2
14 57
5 56
5
19 54 40 24 80
11 2 36 20 76

Sample Output
Case 1: 341
Case 2: 5996
題意:給你多種不同的數錢的方法,求滿足要求的最少的錢數。
思路:猛然間一看好像是關於中國剩余定理的題,但是這一題的模數不一定是兩兩互質。因此可以用解模線性方程組的方法來做,這就要求必須了解擴展歐幾裡得算法,下面說一下解模線性方程組的方法,思想:不斷的進行兩兩合並,即可求得。我們先可以先找兩個同余方程 設通解為N,N=r1(mod(m1)),N=r2(mod(m2)),顯然可以化為k1*m1+r1=k2*m2+r2;--->k1*m1+(-k2*m2)=r2-r1;設a=m1,b=m2,x=k1,y=(-k2),c=r2-r1方程可寫為ax+by=c;由擴展歐幾裡得解得x即可,那麼將x化為原方程的最小正整數解,(x*(c/d)%(b/d)+(b/d))%(b/d);那麼這個x就是原方程的最小整數解。所以N=a*(x+n*(b/d))+r1====N=(a*b/d)*n+(a*x+r1),這裡只有n為未知數所以又是一個N=(a*x+r1)(mod(a*b/d))的式子,然後只要不斷的將兩個式變成一個式子,最後就能解出這個方程組的解
AC代碼:
[cpp] 
#include<iostream> 
#include<string.h> 
#include<string> 
#include<cstdio> 
#define N 7 
using namespace std; 
int M[N],A[N]; 
int Gcd(int a,int b) 
{return b==0?a:Gcd(b,a%b);} 
void gcd(int a,int b,int &d,int &x,int &y) 

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

int main() 

    int T; 
    scanf("%d",&T); 
    for(int k=1;k<=T;++k) 
    { 
        int n; 
        scanf("%d",&n); 
        for(int i=0;i!=n;++i) scanf("%d",&M[i]); 
        for(int i=0;i!=n;++i) scanf("%d",&A[i]); 
        int x,y,d; 
        int a=M[0],c1=A[0]; 
        bool flag=false; 
        for(int i=1;i<n;++i) 
        {   
            int b=M[i]; 
            int c=A[i]-c1; 
            gcd(a,b,d,x,y); 
            if(c%d){flag=true;break;} 
            int r=b/d; 
             x=(c/d*x%r+r)%r; 
             c1=a*x+c1; 
             a=a*r; 
        } 
        if(flag) printf("Case %d: -1\n",k); 
        else 
        { 
            int ans=1; 
            if(c1==0)//特殊情況當所有余數都為0時 
            { 
                for(int i=0;i!=n;++i) 
                    ans=M[i]/Gcd(ans,M[i])*ans; 
                printf("Case %d: %d\n",k,ans); 
            } 
            else printf("Case %d: %d\n",k,c1); 
        } 
    }return 0; 


作者:smallacmer

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved