您的位置:首页 > 编程语言 > C语言/C++

第四十讲 项目 用穷举法解题

2016-10-15 20:26 253 查看
任务和代码:

【项目1-小明借书】

小明有五本新书,要借给A,B,C三位小朋友,若每人每次只能借一本,则可以有多少种不同的借法?

提示:本问题实际上是一个排列问题,即求从5个中取3个进行排列的方法的总数。首先对五本书从1至5进行编号,然后使用穷举的方法。假设三个人分别借这五本书中的一本,当三个人所借的书的编号都不相同时,就是满足题意的一种借阅方法。

/*
*Copyright (c) 2016, CSDN学院
*All rights reserved.
*文件名:main.c
*作者:DylanLiu
*完成日期:2016/10/15
*版本号:V1.0
*
*问题描述:小明有五本新书,要借给A,B,C三位小朋友,若每人每次只能借一本,则可以有多少种不同的借法?。
*程序输出:总共的借书方法。
*/

#include <stdio.h>

int main()
{
int a, b, c, count=0;
for (a=1; a<=5; a++){
for (b=1; b<=5; b++){
for (c=1; c<=5; c++){
if (a!=b && a!=c && b!=c)
count++;
}
}
}
printf("总共有%d种借书方法。\n", count);

return 0;
}


输出结果:



任务和代码:

【项目2-水仙花数】

对于三位数字,若各位数字立方和等于该数,该数就是水仙花数。如153:153=1^3+5^3+3^3

/*
*Copyright (c) 2016, CSDN学院
*All rights reserved.
*文件名:main.c
*作者:DylanLiu
*完成日期:2016/10/15
*版本号:V1.0
*
*问题描述:判断一个数是否为水仙花数。
*程序输出:水仙花数。
*/

#include <stdio.h>

int main()
{
int num=0;
int a, b, c;

printf("Input a number:");
scanf("%d", &num);
a = num /100;
b= num/10%10;
c= num%10;
//printf("a=%d\tb=%d\tc=%d\n", a, b, c);//测试a, b, c分离是否正确
if ((a*a*a+b*b*b+c*c*c)==num)
printf("%d是水仙花数!\n", num);
else
printf("%d不是水仙花数!\n", num);

return 0;
}


输出结果:



任务和代码:

【项目3-鸡兔共笼】

鸡兔共有30只,脚共有90只,问鸡兔各有多少?

/*
*Copyright (c) 2016, CSDN学院
*All rights reserved.
*文件名:main.c
*作者:DylanLiu
*完成日期:2016/10/15
*版本号:V1.0
*
*问题描述:鸡兔同笼。
*程序输出:鸡和兔的数量。
*/

#include <stdio.h>
int main()
{
int i;  //i代表鸡,则兔为30-i只
for(i=0; i<=15; i++)
if(2*i + 4*(30-i)==90)
{
printf("鸡: %d, 兔: %d\n", i, 30-i);
}
return 0;
}


输出结果:



任务和代码:

【项目4-换分币】

用一元人民币兑换成1分、2分和5分硬币,有多少种不同的兑换方法?请输出所有可能的方案。

提示:根据题意设i,j,k分别为兑换的1分、2分、5分硬币的枚数,则i,j,k的值应满足:i+j*2+k*5=100,根据取值范围构造循环解题即可。

/*
*Copyright (c) 2016, CSDN学院
*All rights reserved.
*文件名:main.c
*作者:DylanLiu
*完成日期:2016/10/15
*版本号:V1.0
*
*问题描述:用一元人民币兑换成1分、2分和5分硬币,有多少种不同的兑换方法?请输出所有可能的方案。。
*程序输出:所有满足题目条件的方案。
*/

#include <stdio.h>

int main()
{
int  a=0, b=0, c=0;
int count=0;

for(b=0; b<=50; b++){
for (c=0; c<=20; c++){
for (a=0; a<=100; a++)
if ((a*1+b*2+c*5)==100)
count++;
}
}
printf("一共有%d种兑换方法。\n", count);

return 0;
}


输出结果:



任务和代码:

【项目5-年龄几何】

张三、李四、王五、刘六的年龄成一等差数列,他们四人的年龄相加是26,相乘是880,求以他们的年龄为前4项的等差数列的前20项。

提示:设数列的首项为n,公差为a,则前4项之和为”4*n+6*a”,前4 项之积为”n*(n+a)(n+a+a)(n+a+a+a)”。同时”1<=a<=4”,”1<=n<=6”。可采用穷举法求出此数列。

/*
*Copyright (c) 2016, CSDN学院
*All rights reserved.
*文件名:main.c
*作者:DylanLiu
*完成日期:2016/10/15
*版本号:V1.0
*
*问题描述:张三、李四、王五、刘六的年龄成一等差数列,他们四人的年龄相加是26,相乘是880,求以他们的年龄为前4项的等差数列的前20项。。
*程序输出:等差数列的和。
*/

#include <stdio.h>
int main()
{
int a,n,i,s;//n为首项, a为公差, s为数列
for(a=1; a<=4; a++)
for(n=1; n<=6; n++)
if(n*4+a*6==26 && n*(n+a)*(n+a+a)*(n+a+a+a)==880)
{
printf("%d", n);
for(i=1; i<20; i++)//前20项只有19个公差
{
s=n+a*i;
printf(", %d", s);  //后面的19个都和前一个用逗号分隔输出
}
printf("\n");
}
return 0;
}


输出结果:



任务和代码:

项目6-三色球问题】

若一个口袋中放有12个球,其中有3个红的。3个白的和6个黒的,问从中任取8个共有多少种不同的颜色搭配?

提示:设任取的红球个数为i,白球个数为j,则黒球个数为8-i-j,根据题意红球和白球个数的取值范围是0~3,在红球和白球个数确定的条件下,黒球个数取值应为8-i-j<=6。

/*
*Copyright (c) 2016, CSDN学院
*All rights reserved.
*文件名:main.c
*作者:DylanLiu
*完成日期:2016/10/15
*版本号:V1.0
*
*问题描述:三色球问题。。
*程序输出:总共的组合方法。
*/

#include <stdio.h>

int main()
{

int red=0, white=0;
int count=0;

for (red=0; red<=3; red++)
for (white=0<
fda2
/span>; white<=3; white++){
if((8-red-white<=6) && (8-red-white>=2)){
count++;
printf("第%d种分法:\n", count);
printf("red=%d\twhite=%d\tblack=%d\n", red, white, 8-red-white);
}
}

return 0;
}




任务和代码:

【项目7-找数字】

(1)求满足下式的 x,y,z

[plain] view plain copy print?在CODE上查看代码片派生到我的代码片
x y z
+  y z z
──────
5 3 2


请补充完整下面的程序:

[cpp] view plain copy print?在CODE上查看代码片派生到我的代码片
#include <stdio.h>
int main()
{
int x,y,z,i,result=532;
for (x=1;___(1)___; x++)
for (y=1; ___(2)___; y++)
for ( ___(3)___;___(4)___; z++)
{
i=___(5)___+(100*y+10*z+z);
if (i==result)
printf("x=%d, y=%d, z=%d\n",x,y,z);
}
return 0;
}


(2)在下面的加法算式中,不同的符号代表不同的数字,相同的符号代表相同的数字。请设计程序求出”都、要、学、C”4个符号分别代表的数字。

[plain] view plain copy print?在CODE上查看代码片派生到我的代码片
C
学  C
要  学  C
+ 都  要  学  C
________________
2   0   0   8


提示:让计算机解奥数题。穷举”都、要、学、C”4个符号分别代表的数字(从0到9),然后进行组合,如果组合起来符合规则(不同的符号代表不同的数字,相同的符号代表相同的数字,且使等式成立),则为正解。

**************************************

(1)的解:

/*
*Copyright (c) 2016, CSDN学院
*All rights reserved.
*文件名:main.c
*作者:DylanLiu
*完成日期:2016/10/15
*版本号:V1.0
*
*问题描述:求满足条件的x, y, z。
*程序输出:x, y, z。
*/

#include <stdio.h>

int main()
{
int x,y,z,i,result=532;
for (x=1; x<=5; x++)
for (y=1; y<=5; y++)
{
z=1;//经过分析,z的值只可能是1或6,再分析得z只能为1
i=(x*100+y*10+z)+(100*y+10*z+z);
if (i==result)
printf("x=%d, y=%d, z=%d\n",x,y,z);
}
return 0;
}


输出结果:



**************************************

(2)的解:

/*
*Copyright (c) 2016, CSDN学院
*All rights reserved.
*文件名:main.c
*作者:DylanLiu
*完成日期:2016/10/16
*版本号:V1.0
*
*问题描述:。
*程序输出:。
*/

#include <stdio.h>

int main()
{
int d=0, y=0, x=0, c=0, s=0;

for (y=0; y<=5; y++)//“要”代表的数最多只能进两位
for (d=0; d<=2; d++)//“都”代表的数最多为2
for(x=0; x<=6; x++)//x只能是6或0
for (c=0; c<=7; c++){//c只能是2或7
if((d-y)*(d-x)*(d-c)*(y-x)*(y-c)*(x-c)!=0)//一个技巧:表示两两不同可以这样做
{
s=4*c+3*x*10+2*y*100+d*1000;
if(2008==s)
printf("都:%d 要:%d 学:%d C:%d\n", d, y, x, c);
}
}

return 0;
}


输出结果:



任务和代码:

【项目8-谁是小偷】

警察局抓住了A、B、C、D四名盗窃嫌疑犯,其中只有一人是小偷。在审问时,A说:“我不是小偷”;B说:“C是小偷”;C说:“小偷肯定是D”;D说:“C在冤枉好人”。现在已经知道这四人中有三人说的是真话,一人说的是假话。请问到底谁是小偷?

提示:设4个变量a,b,c,d,为0时表示不是小偷,为1时表示是小偷,用四重循环穷举a,b,c,d可能的取值的组合,对每一种组合判断其是否符合题目中给出的约束。最后结论:C是小偷。

/*
*Copyright (c) 2016, CSDN学院
*All rights reserved.
*文件名:main.c
*作者:DylanLiu
*完成日期:2016/10/16
*版本号:V1.0
*
*问题描述:警察局抓住了A、B、C、D四名盗窃嫌疑犯,其中只有一人是小偷。在审问时,A说:“我不是小偷”;
B说:“C是小偷”;C说:“小偷肯定是D”;D说:“C在冤枉好人”。现在已经知道这四人中有三人说的是
真话,一人说的是假话。请问到底谁是小偷? 。
*程序输出:小偷的代号。
*/

#include <stdio.h>

int main()
{
int a=0, b=0, c=0, d=0;

//0代表不是小偷,1代表是小偷
//穷举
for (a=0; a<=1; a++)
for (b=0; b<=1; b++)
for (c=0; c<=1; c++)
for (d=0; d<=1; d++){
if (((!a)+c+d+(!d)==3) && (a+b+c+d==1))//!a表示a说的话(a不是小偷),只有3个人真话, 一定有1个小偷
if (a==1)
printf("a是小偷!\n");
else if (b==1)
printf("b是小偷!\n");
else if (c==1)
printf("c是小偷!\n");
else
printf("d是小偷\n");
}

return 0;
}


输出结果:



任务和代码:

【项目9-污损的单据】

(1)有等式[※×(※3+※)]^2=8※※9,其中※处为1个数字,滴上了墨水无法辨认。请编程找出※表示哪个数字。

#include <stdio.h>
int main()
{
int a,b,c,d,e,s;
for(a=0;a<=9;a++)
{
for(b=0;b<=9;b++)
{
for(c=0;c<=9;c++)
{
for(d=0;d<=9;d++)
{
for(e=0;e<=9;e++)
{
s=a*(b*10+3+c);
if (s*s==8000+d*100+e*10+9)
{
printf("等式为:[%d×(%d3+%d)]^2=8%d%d9\n",a,b,c,d,e);  //※×(※3+※)]^2=8※※9
}
}
}
}
}
}
return 0;
}


输出结果:



(2)有等式[※×(※3○※)]^2=8※※9,其中※处为1个数字,○处为+、-、×、÷四个运算符之一,现滴上了墨水无法辨认。请编程找出※表示哪个数字,○表示哪个运算符。

/*
*Copyright (c) 2016, CSDN学院
*All rights reserved.
*文件名:main.c
*作者:DylanLiu
*完成日期:2016/10/16
*版本号:V1.0
*
*问题描述:(1)有等式[※×(※3+※)]^2=8※※9,其中※处为1个数字,滴上了墨水无法辨认。请编程找出※表示哪个数字。
*程序输出:※表示的数字。
*/

#include <stdio.h>

int main()
{
int a,b,c,d,e,s;
for(a=0;a<=9;a++)
{
for(b=0;b<=9;b++)
{
for(c=0;c<=9;c++)
{
for(d=0;d<=9;d++)
{
for(e=0;e<=9;e++)
{
s=a*(b*10+3+c);
if (s*s==8000+d*100+e*10+9)
printf("原式为:\n[%dx(%d3+%d)]^2=8%d%d9\n", a, b, c, d, e);
s=a*(b*10+3-c);
if (s*s==8000+d*1100+e*10+9)
printf("原式为:\n[%dx(%d3-%d)]^2=8%d%d9\n", a, b, c, d, e);
s=a*((b*10+3)*c);
if (s*s==8000+d*100+e*10+9)
printf("原式为:\n[%dx(%d3x%d)]^2=8%d%d9\n", a, b, c, d, e);
if (c!=0){
s=a*((b*10+3)/c);
if (s*s==8000+d*100+e*10+9)
printf("原式为:\n[%dx(%d3/%d)]^2=8%d%d9\n", a, b, c, d, e);
}
}
}
}
}
}

return 0;
}


输出结果:



/*************************************************************/

总结:穷举法虽然在有些程序当中逻辑关系比较简单,但是经过人为的分析之后能减少循环的次数,达到优化程序的作用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言