您的位置:首页 > 其它

ACM-韩信点兵【中国剩余定理-孙子定理】

2016-05-02 21:02 211 查看

题目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>

using namespace std;


int hanxindianbing(int a,int b,int c){



for(int i = 7+c; i <100;i=i+7)

{

if(i%3==a&&i%5==b)

return i;


}

return 0;

}

int main(){


while (1){


int a,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必须为最小公倍数


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: