题目是:韩信点兵
Time Limit:
1000MS Memory
Limit:65536
Description :
带队人员想知道一共有多少人参加了活动。
于是分别让同学们
6人一列,5人一列,7人一列,13人一列站队。
现已知各种站队的余项,试求最少有多少人参加了这次的活动。
Input
四个正整数,用空格分开
Output
最少的人数。
Sample Input
1 1 4 11
2 3 2 8
Sample Output
1831
1178
算法分析:
韩信点兵是种类型的算法,举个例子就知道怎么解这种算法问题了:
相传韩信带兵时有次急需清点人数。他只大概知道人数在1000-1100。
于是他命令士兵3人一排,结果多出2名;接着命令士兵5人一排,结果多出3名;
他又命令士兵7人一排,结果又多出2名。然后韩信马上向将士们宣布:我军有1073名勇士!那他是怎么算出的呢?
1:先算6、5、7、13的最小公倍数6*5*7*13=2730
2:再算符合除以6余2,除以5余3,除以7余2,除以13余1的最小值: 除以3余2的数:5, 8, 11, 14, 17, 20, 23,
26…
除以5余3的数:8, 13, 18, 23, 28…
除以7余2的数:9,16,23,30…
由上得出除以3余2,除以5余3,除以7余2的最小值为23
韩信原有1500名士兵,苦战一场死伤四五百。
现剩余士兵应在1000-1100之间,并且现存的士兵数应可以被105整除并且余数是23.
所以现存士兵数应该是105×10+23=1073人。
在上面这道ACM题里,只需算出最小值即可,即只要算出第2步里的最小值,那就是答案了,下面是程序:
//点击下载韩信点兵.c
#include
#include
int main()
{
int i, max, flag;
int dividend[4], divisor[4], quotient[4], remainder[4];
divisor[0] = 6;
divisor[1] = 5;
divisor[2] = 7;
divisor[3] = 13;
while(EOF != scanf("%d%d%d%d", remainder, remainder+1, remainder+2,
remainder+3))
{
memset(quotient, 0, sizeof(quotient));
while(1)
{
for(i=0; i<4; i++)
{
dividend[i] = divisor[i]*quotient[i] + remainder[i];
}
max = 0;
for(i=0; i<4; i++)
{
if(max < dividend[i])
max = dividend[i];
}
flag = 1;
for(i=0; i<4; i++)
{
if(max != dividend[i])
{
flag = 0;
quotient[i]++;
}
}
if(flag)
break;
}
printf("%d\n", dividend[0]);
}
return 0;
}