第四十课 问题求解方法——穷举 【项目1-9】
2016-01-11 23:00
330 查看
第四十课 问题求解方法——穷举
项目一 【小明借书】
小明有五本新书,要借给A,B,C三位小朋友,若每人每次只能借一本,则可以有多少种不同的借法?
提示:本问题实际上是一个排列问题,即求从5个中取3个进行排列的方法的总数。首先对五本书从1至5进行编号,然后使用穷举的方法。假设三个人分别借这五本书中的一本,当三个人所借的书的编号都不相同时,就是满足题意的一种借阅方法。
代码:
运行结果:
======================================================================================================================
项目二 【水仙花数】
对于三位数字,若各位数字立方和等于该数,该数就是水仙花数。如153:153=13+53+33
代码:
运行结果:
======================================================================================================================
项目三 【鸡兔共笼】
鸡兔共有30只,脚共有90只,问鸡兔各有多少?
代码:
======================================================================================================================
项目四 【换分币】
用一元人民币兑换成1分、2分和5分硬币,有多少种不同的兑换方法?请输出所有可能的方案。
提示:根据题意设i,j,k分别为兑换的1分、2分、5分硬币的枚数,则i,j,k的值应满足:i+j*2+k*5=100,根据取值范围构造循环解题即可。
代码:
运行结果:
======================================================================================================================
项目五 【年龄几何】
张三、李四、王五、刘六的年龄成一等差数列,他们四人的年龄相加是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"。可采用穷举法求出此数列。
代码:
运行结果:
======================================================================================================================
项目六 【三色球问题】
若一个口袋中放有12个球,其中有3个红的。3个白的和6个黒的,问从中任取8个共有多少种不同的颜色搭配?
提示:设任取的红球个数为i,白球个数为j,则黒球个数为8-i-j,根据题意红球和白球个数的取值范围是0~3,在红球和白球个数确定的条件下,黒球个数取值应为8-i-j<=6。
代码:
======================================================================================================================
项目七 【找数字】
(1)求满足下式的 x,y,z
[plain] view
plaincopyprint?
x y z
+ y z z
──────
5 3 2
请补充完整下面的程序:
[cpp] view
plaincopyprint?
#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
plaincopyprint?
C
学 C
要 学 C
+ 都 要 学 C
________________
2 0 0 8
提示:让计算机解奥数题。穷举"都、要、学、C"4个符号分别代表的数字(从0到9),然后进行组合,如果组合起来符合规则(不同的符号代表不同的数字,相同的符号代表相同的数字,且使等式成立),则为正解。
(1)代码:
运行结果:
(2)代码:
======================================================================================================================
项目八 【谁是小偷】
警察局抓住了A、B、C、D四名盗窃嫌疑犯,其中只有一人是小偷。在审问时,A说:“我不是小偷”;B说:“C是小偷”;C说:“小偷肯定是D”;D说:“C在冤枉好人”。现在已经知道这四人中有三人说的是真话,一人说的是假话。请问到底谁是小偷?
提示:设4个变量a,b,c,d,为0时表示不是小偷,为1时表示是小偷,用四重循环穷举a,b,c,d可能的取值的组合,对每一种组合判断其是否符合题目中给出的约束。最后结论:C是小偷。
代码:
======================================================================================================================
项目九 【污损的单据】
(1)有等式[※×(※3+※)]2=8※※9,其中※处为1个数字,滴上了墨水无法辨认。请编程找出※表示哪个数字。
(2)有等式[※×(※3○※)]2=8※※9,其中※处为1个数字,○处为+、-、×、÷四个运算符之一,现滴上了墨水无法辨认。请编程找出※表示哪个数字,○表示哪个运算符。
(1)代码:
(2)代码:
======================================================================================================================
总结:
这一课主要用循环的特性来做嵌套,让计算机完成穷举来得到结果,穷举的效率本来就低,应该尽可能的减少不必要的循环次数,来减少无用功。
180
项目一 【小明借书】
小明有五本新书,要借给A,B,C三位小朋友,若每人每次只能借一本,则可以有多少种不同的借法?
提示:本问题实际上是一个排列问题,即求从5个中取3个进行排列的方法的总数。首先对五本书从1至5进行编号,然后使用穷举的方法。假设三个人分别借这五本书中的一本,当三个人所借的书的编号都不相同时,就是满足题意的一种借阅方法。
代码:
#include<stdio.h> int main() { int a,b,c,i=0; for(a=1;a<=5;a++) for(b=1;b<=5;b++) for(c=1;c<=5;c++) if(a!=b&&b!=c&&a!=c) { if(i%6==0) printf("\n"); printf("%d %d %d ",a,b,c); i++; } printf("\n共%d种借法\n",i); return 0; }
运行结果:
======================================================================================================================
项目二 【水仙花数】
对于三位数字,若各位数字立方和等于该数,该数就是水仙花数。如153:153=13+53+33
代码:
#include<stdio.h> int main() { int a,b,c,num; for(a=1;a<=9;a++) for(b=0;b<=9;b++) for(c=0;c<=9;c++) { num=a*100+b*10+c; if(num==a*a*a+b*b*b+c*c*c) printf("%d ",num); } printf("\n"); return 0; }
运行结果:
======================================================================================================================
项目三 【鸡兔共笼】
鸡兔共有30只,脚共有90只,问鸡兔各有多少?
代码:
#include<stdio.h> int main() { int a,b; for(a=0;a<=30;a++) { b=30-a; if((a+2*b)==45) printf("鸡%d,兔%d\n",a,b); } return 0; }运行结果:
======================================================================================================================
项目四 【换分币】
用一元人民币兑换成1分、2分和5分硬币,有多少种不同的兑换方法?请输出所有可能的方案。
提示:根据题意设i,j,k分别为兑换的1分、2分、5分硬币的枚数,则i,j,k的值应满足:i+j*2+k*5=100,根据取值范围构造循环解题即可。
代码:
#include<stdio.h> int main() { int i,j,k,n=0; for(i=0;i<=100;i++) for(j=0;j<=50;j++) for(k=0;k<=20;k++) if((i+j*2+k*5)==100) { printf("一分%d,二分%d,五分%d\n",i,j,k); n++; } printf("共%d种换法\n",n); return 0; }
运行结果:
======================================================================================================================
项目五 【年龄几何】
张三、李四、王五、刘六的年龄成一等差数列,他们四人的年龄相加是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"。可采用穷举法求出此数列。
代码:
#include<stdio.h> int main() { int n,a,i; for(n=1;n<=6;n++) for(a=1;a<=4;a++) if((4*n+6*a)==26&&(n*(n+a)*(n+a+a)*(n+a+a+a))==880) for(i=1;i<=20;i++) { printf("%d ",n); n=n+a; } printf("\n"); return 0; }
运行结果:
======================================================================================================================
项目六 【三色球问题】
若一个口袋中放有12个球,其中有3个红的。3个白的和6个黒的,问从中任取8个共有多少种不同的颜色搭配?
提示:设任取的红球个数为i,白球个数为j,则黒球个数为8-i-j,根据题意红球和白球个数的取值范围是0~3,在红球和白球个数确定的条件下,黒球个数取值应为8-i-j<=6。
代码:
#include<stdio.h> int main() { int i,j,k,n=0; for(i=0;i<=3;i++) for(j=0;j<=3;j++) { k=8-i-j; if(k<=6) { printf("红球%d,白球%d,黑球%d\n",i,j,k); n++; } } printf("共%d种选择\n",n); return 0; }运行结果:
======================================================================================================================
项目七 【找数字】
(1)求满足下式的 x,y,z
[plain] view
plaincopyprint?
x y z
+ y z z
──────
5 3 2
请补充完整下面的程序:
[cpp] view
plaincopyprint?
#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
plaincopyprint?
C
学 C
要 学 C
+ 都 要 学 C
________________
2 0 0 8
提示:让计算机解奥数题。穷举"都、要、学、C"4个符号分别代表的数字(从0到9),然后进行组合,如果组合起来符合规则(不同的符号代表不同的数字,相同的符号代表相同的数字,且使等式成立),则为正解。
(1)代码:
#include<stdio.h> int main() { int x,y,z,i,result=532; for(x=1;x<=5;x++) for(y=1;y<=5;y++) for(z=1;z<=9;z++) { 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)代码:
#include<stdio.h> int main() { int a,b,c,d,sum; for(d=0;d<=7;d++) for(c=0;c<=9;c++) for(b=0;b<=9;b++) for(a=0;a<=2;a++) if(a!=b&&a!=c&&a!=d&&b!=c&&b!=d&&c!=d) { sum=d*4+c*30+b*200+a*1000; if(sum==2008) printf("都%d,要%d,学%d,c%d\n",a,b,c,d); } return 0; }运行结果:
======================================================================================================================
项目八 【谁是小偷】
警察局抓住了A、B、C、D四名盗窃嫌疑犯,其中只有一人是小偷。在审问时,A说:“我不是小偷”;B说:“C是小偷”;C说:“小偷肯定是D”;D说:“C在冤枉好人”。现在已经知道这四人中有三人说的是真话,一人说的是假话。请问到底谁是小偷?
提示:设4个变量a,b,c,d,为0时表示不是小偷,为1时表示是小偷,用四重循环穷举a,b,c,d可能的取值的组合,对每一种组合判断其是否符合题目中给出的约束。最后结论:C是小偷。
代码:
#include<stdio.h> int main() { int a,b,c,d; 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==0&&c==1&&d==1)||(a==0&&d==1&&d==0)||(a==0&&c==1&&d==0)||(c==1&&d==1&&d==0)) if(a+b+c+d==1) printf("a%d,b%d,c%d,d%d\n",a,b,c,d); } return 0; }运行结果:
======================================================================================================================
项目九 【污损的单据】
(1)有等式[※×(※3+※)]2=8※※9,其中※处为1个数字,滴上了墨水无法辨认。请编程找出※表示哪个数字。
(2)有等式[※×(※3○※)]2=8※※9,其中※处为1个数字,○处为+、-、×、÷四个运算符之一,现滴上了墨水无法辨认。请编程找出※表示哪个数字,○表示哪个运算符。
(1)代码:
#include<stdio.h> int main() { int a,b,c,d,e,n; 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++) { n=a*(b*10+3+c); if(n*n==(8000+d*100+e*10+9)) printf("[%dx(%d+%d)]^2=%d\n",a,b*10+3,c,8000+d*100+e*10+9); } return 0; }运行结果:
(2)代码:
#include<stdio.h> int main() { int a,b,c,d,e,n; 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++) { n=a*(b*10+3+c); if(n*n==(8000+d*100+e*10+9)) printf("[%dx(%d+%d)]^2=%d\n",a,b*10+3,c,8000+d*100+e*10+9); n=a*(b*10+3-c); if(n*n==(8000+d*100+e*10+9)) printf("[%dx(%d-%d)]^2=%d\n",a,b*10+3,c,8000+d*100+e*10+9); n=a*((b*10+3)*c); if(n*n==(8000+d*100+e*10+9)) printf("[%dx(%dx%d)]^2=%d\n",a,b*10+3,c,8000+d*100+e*10+9); if(c!=0) { n=a*((b*10+3)/c); if(n*n==(8000+d*100+e*10+9)) printf("[%dx(%d/%d)]^2=%d\n",a,b*10+3,c,8000+d*100+e*10+9); } } return 0; }运行结果:
======================================================================================================================
总结:
这一课主要用循环的特性来做嵌套,让计算机完成穷举来得到结果,穷举的效率本来就低,应该尽可能的减少不必要的循环次数,来减少无用功。
180
相关文章推荐
- Mysql几种索引类型的区别及适用情况
- 文件子系统的调优
- 14.6 Spring MVC 测试框架(翻译)
- 利用KeyChain共享数据(唯一标示)
- 一起talk C栗子吧(第九十七回:C语言实例--使用消息队列进行进程间通信一)
- oracle数据库不支持mysql中limit功能
- Nginx详解-服务器集群
- 配置本地Yum源
- BZOJ 3110 ZJOI 2013 K大值查询 线段树套线段树
- 计算机组件及操作系统基础知识
- query 中 (function( window, undefined ) {})(window)写法详解(转)
- POJ【1502】MPI Maelstrom
- Lessons learned developing a practical large scale machine learning system
- 招收实习生是为了什么?
- TCP/IP子系统的调优
- 原型而上之成果模型之垂直社交
- 第四十三课 从文本文件中读入数据 【项目1-4】
- 【jsp+servelt】Using <c:set target>
- 1113: [Poi2008]海报PLA 单调栈
- Guava包学习--Table