C语言韩信点兵(容易超时)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言韩信点兵(容易超时)相关的知识,希望对你有一定的参考价值。

韩信点兵

Time Limit:1000MS Memory Limit:65536K
Total Submit:43 Accepted:2

Description

韩信是刘邦手下一位杰出的军事家,刘邦得天下,军事上全依靠他。在保守军事机密的时候,他常常能巧妙地运用数学问题。有句歇后语说:韩信点兵——多多益善。其具体做法就是,不断变换士兵的队形,然后只记录最后一列剩余的人数。例如命令士兵1-3报数,记录下最后一个士兵所报的数;命令士兵1-5报数,记录下最后一个士兵所报的数;命令士兵1-7报数,记录下最后一个士兵所报的数。这样韩信就能很快地计算出士兵的总人数。
有一天,汉高祖刘邦问大将军韩信御兵多少?韩信答说,每3人一列余1人、5人一列余2人、7人一列余4人、13人一列余6人、17人一列余2人、19人一列余10人、23人一列余1人、29人一列余11人。

Input

要求由键盘输入A,B,C,D,E,F,G,H,a,b,c,d,e,f,g,h十六个数,分别代表每A人一列余a、每B人一列余b、每C人一列余c、每D人一列余D、每E人一列余e、每F人一列余f、每G人一列余g、每H人一列余h,其中A,B,C,D,E,F,G,H为互不相等的质数。输入数据为两行,每行H个数,每个数据间用空格分隔.
第一行8个数分别为A,B,C,D,E,F,G,H。第二行8个数分别为a,b,c,d,e,f,g,h

Output

输出总兵士数,要求输出满足条件的最小的一个,但要满足8种排法的每一种排法至少可排一列。(保证给的数据,有结果且计算的结果不会超过2的63次方)

Sample Input

3 5 7 13 17 19 23 29
1 2 4 6 2 10 1 11

Sample Output

1306792

递归的思想,1个队列的话,3余1,明显就是3x+1,最小x=1;和为4
两个队列,5余2,,首先他要满足4+3x的形式,才能满足1,找最小的x使3x+4%5=2;5次以内必找到,和为7;
三个队列7+(3*5)x%7=4;7次必找到;可以得出最多只要计算A+B+C+D+E+F+G+H次的乘法和除法,不可能超1000MS。
参考技术A Sample Input
3 5 7 13 17 19 23 29
1 2 4 6 2 10 1 11
Sample Output
1306792
这个结果不对啊,1306792取余29是23,不是11!
用下面的程序,输出结果是224399662!

#include <stdio.h>

void main()

unsigned int i;
unsigned int col[8];
unsigned int rem[8];
unsigned long col_count;
unsigned int item;
unsigned long total;

while(1)

total = 0xffffffff;
printf("total(0xffffffff) = %lu\n",total);
printf("1: Start\n");
printf("0: Exit\n");
printf("Please select the operation:\n");
scanf("%d",&item);
if(item != 1)
break;
printf("Please input the condition:\n");
scanf("%d %d %d %d %d %d %d %d",&col[0],&col[1],&col[2],&col[3],&col[4],&col[5],&col[6],&col[7]);
scanf("%d %d %d %d %d %d %d %d",&rem[0],&rem[1],&rem[2],&rem[3],&rem[4],&rem[5],&rem[6],&rem[7]);
printf("Calculating,please waiting...\n");
printf("%d %d %d %d %d %d %d %d\n",col[0],col[1],col[2],col[3],col[4],col[5],col[6],col[7]);
printf("%d %d %d %d %d %d %d %d\n",rem[0],rem[1],rem[2],rem[3],rem[4],rem[5],rem[6],rem[7]);

item = 2;
col_count = 0;
while(1)

col_count ++;
total = col_count * col[7] + rem[7];
for(i=0; i<7; i++)

if((total % col[i]) != rem[i])
break;

if(i>=7)
break;
if(total >= (0xffffffff - col[7] - rem[7]))

printf("No result! Continue?(1:yes 0:no)");
scanf("%d",&item);
break;


if(item == 1)
continue;
else if(item == 0)
break;
else

printf("i = %d\n",i);
printf("The total army is: %lu\n",total);
printf("Continue?(1:yes 0:no)");
scanf("%d",&item);
if(item == 0)
break;


参考技术B 用c语言编程问题补充:最后答案是1051! #include 参考技术C 4274527

韩信点兵

/*
    韩信点兵
    相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排、五人一排、七人一排地变换队
    形,而他每次只掠一眼队伍的排尾就知道总人数了。输入多组数据,每组数据包含3个非负整数a,b,c,表示每种
    队形排尾的人数(a<3,b<5,c<7),输出总人数的最小值(或报告无解)。已知总人数不小于10,不超过100.输入
    到文件结束为止。
*/
# define LOCAL
#include<stdio.h>
#include<time.h>

int main(){
#ifdef LOCAL
    freopen("data.in","r", stdin);
    freopen("data.out","w", stdout);
#endif // LOCAL

    int a, b, c;
    int peoples, cases=0;
    while(scanf("%d %d %d", &a, &b, &c) == 3){
        cases++;

        peoples = -1;
        for(int i = 10; i < 100; i++){
            if((i % 3 == a) && (i % 5 == b) && (i % 7 == c)){
                peoples = i;
            }
        }
        if(peoples > 0){
             printf("Case %d: %d\n", cases, peoples);
        } else {
            printf("Case %d: No Answer\n", cases);
        }
    }

    return 0;
}
/*
[input]
2 1 6
2 1 3

[output]
Case 1: 41
Case 2: No Answer
*/

  

以上是关于C语言韩信点兵(容易超时)的主要内容,如果未能解决你的问题,请参考以下文章

c语言韩信点兵

C语言编程:韩信点兵问题拜托各位了 3Q

关于大一的C语言问题,韩信点兵。。

C语言,韩信点兵编程,看看我的错在哪?

c语言编程序:韩信点兵,韩信有一队伍,你想知道有多少人,就让士兵报数,按从1至5报数,最末一个士兵报的

c语言简单程序