1. 程式人生 > >ACM-韓信點兵【中國剩餘定理-孫子定理】

ACM-韓信點兵【中國剩餘定理-孫子定理】



題目34---韓信點兵
時間限制:3000 ms  |  記憶體限制:65535 KB
難度:1
描述
相傳韓信才智過人,從不直接清點自己軍隊的人數,只要讓士兵先後以三人一排、五人一排、七人一排地變換隊形,而他每次只掠一眼隊伍的排尾就知道總人數了。輸入3個非負整數a,b,c ,表示每種隊形排尾的人數(a<3,b<5,c<7),輸出總人數的最小值(或報告無解)。已知總人數不小於10,不超過100 。
輸入
輸入3個非負整數a,b,c ,表示每種隊形排尾的人數(a<3,b<5,c<7)。例如,輸入:2 4 5
輸出
輸出總人數的最小值(或報告無解,即輸出No answer)。例項,輸出:89
樣例輸入
2 1 6樣例輸出
41
 

我的答案:

#include<iostream>

usingnamespacestd;
inthanxindianbing(inta,intb,intc){
for(inti=7+c;i<100;i=i+7)
{
if(i%3==a&&i%5==b)
returni;
}
return0;
}
intmain(){
while(1){
inta,b,c;
cin>>a>>b>>c;
if(a<3&&b<5&&c<7)
cout<<hanxindianbing(a,b,c)<<endl;
}
}

標準答案如下:

01.#include<iostream> 02.using namespace std; 03.int main() 04.{ 05.int a,b,c; 06.cin>>a>>b>>c; 07.int n=(a*70+b*21+c*15)%105; 08.if(n>100||n<10) cout<<"No answer"<<endl; 09.else cout<<n<<endl; 10.}

 這道題用的是中國剩餘定理,也稱孫子定理從而簡化了程式碼,提高了程式的效率。

其實這道題簡化為已知三個互質的數A,B,C除某個數X的餘數a,b,c和這三個互質的數,求這個X的最小值

如果寫成數學公式就是:

X%A=a;

X%B=b;

X%C=c;

解決問題的方法是首先求出一個儘可能小的數 Y ,使得Y分別除以三個質數時,得到的餘數恰好為a,b,c。然後Y再除以三個互質的數的最小公倍數G,餘數即為X。

所以首先要找到這個數Y:

找到這個數Y的方法是先找到三個數M,N,P:M分別除以三個質數時,得到的餘數為a,0,0;N時,餘數為0,b,0;P時,餘數為0,0,c。

如此,Y = M+N+P。就可以得到想要的Y。

然後是找到數M,N,P的方法:

這裡舉例找數M的方法,其它同理:若要使M%B==M%C=0、M%A=a,則M必為B與C的公倍數

所以先求出B與C的公倍數T,然後用T和T的倍數與A相除,直到找到餘數為1的較小值Q(不必要求是最小值,只是儘量小方便運算),則M = Q*a;

同理找出另外兩個較小值R,F,則N=R*b,P=F*c。

所以Y=Q*a+R*b+F*c;

則X=(Q*a+R*b+F*c)%G;

當互質的數的數量變為4個,5個,6個,餘數有變化等情況,皆可運用上述定理。

PS:

1 注意題目是否有解,數與數之間必須互質

2 如果數與數之間非互質,則必須符合實際情況,如 3除餘2,9除餘4的條件是不可能的,因為9除餘4,3除4餘1,而不是餘2,則題目不成立。

3 G必須為最小公倍數