韓信點兵 (算法優化 | 非暴力求解)

韓信點兵

相傳韓信才智過人,從不直接清點自己軍隊的人數,只要讓士兵先後以三人一排、五人一排、七人一排地變換隊形,而他每次只掠一眼隊伍的排尾就知道總人數了。輸入3個非負整數a,b,c ,表示每種隊形排尾的人數(a<3,b<5,c<7),輸出總人數的最小值(或報告無解)。已知總人數不小於10,不超過100 。

輸入格式

輸入3個非負整數a,b,c ,表示每種隊形排尾的人數(a<3,b<5,c<7)。

輸出格式

輸出總人數的最小值(或報告無解,即輸出No answer)。

輸入樣例1

2 1 6

輸出樣例1

41

輸入樣例2

2 1 3

輸出樣例2

No answer

定理1

若,a被n除所得的餘數等於b被n除所得的餘數,c被n除所得的餘數等於d被n除所得的餘數, 則a*c被n除所得的餘數等於b*d被n除所得的餘數。

定理2

被除數a加上或減去除數b的倍數,再除以b,餘數不變。

算法原理

先找到能整除其中兩個數,同時除以另一個數時餘數是1的數。

  1. 能被3和5整除的數爲15n,(n>=1)。當n=1時,15除以7餘數是1。
  2. 能被3和7整除的數爲21n,(n>=1)。當n=1時,21除以5餘數是1。
  3. 能被5和7整除的數爲35n,(n>=1)。當n=2時,70除以3餘數是1。

則所求的結果就是 (70a+21b+15c)%(35*7)。

  1. 取餘是爲了得到題目所要求的最小值,根據定理2,可知對最小公倍數取餘可得。
  2. 更進一步的詳細解釋,對於3來說,70a+21b+15c 的多項式中,只有70a除以3會有餘數a,21b+15c可以整除3。以此類比理解5和7。
代碼實現如下
#include<iostream>
using namespace std;

int main(){
    int a,b,c,num;
    cin>>a>>b>>c;
    num=(70*a+21*b+15*c)%105;
    if(num>=10&&num<=100)
    	cout<<num;
	else
		cout<<"No answer";
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章