要求:请编出3个程序来,分别用三种循环语句完成,注意体会各种循环语句的执行过程及语法特点。
【项目2-分数的累加】编程序,输出1/3-3/5+5/7-7/9…+19/21的结果
提示:如果直接解决上面的问题有困难,可以设计一条“由易到难”的路线,逐渐解决其中要解决的问题,让自己的思路明朗起来。
(1)1+2+...+20 ——这个应该会
(2)1+1/2+1/3+…+1/20 ——分数的累加,注意两个整型相除,商也为整型,而显然求和结果应该是小数
(3)1/2+2/3+3/4+…+19/20 ——分子不全是1了,找找规律,稍加改动就好了
(4)1/2-2/3+3/4-…+19/20 ——要累加的值一正一负倒腾,用pow(-1,i)是个效率很低的做法,不推荐使用。技巧:专门设置一个变量s表示累加项的符号,取值随着循环,每次乘以-1,从而在+1、-1之间变化,循环加求和的累加要用累加的项(i/(i+1))乘以这个表示符号的s。
(5)1/3-3/5+5/7-7/9…+19/21 ——这是我们的目标
【项目3:乘法口诀表】编程序,输出一个乘法口诀表,形如
1x1=1
1x2=2 2x2=4
1x3=3 2x3=6 3x3=9
……
【项目4:输出完数】一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如6=1+2+3,再如8的因子和是7(即1+2+4),8不是完数。编程找出1000以内的所有完数。
提示:首先从2到1000构造循环控制变量为i的外层循环。每次循环中,利用内嵌的循环逐个地求出i的因子,并累加起来(为提高效率,可能的因子从1到i/2),如果因子和等于i,则说明是完全数,输出。然后继续循环,考察i+1……
【项目5:贪财的富翁】一个百万富翁遇到一个陌生人,陌生人找他谈一个换钱的计划,该计划如下:我每天给你十万元,而你第一天只需给我一分钱,第二天我仍给你十万元,你给我两分钱,第三天我仍给你十万元,你给我四分钱,....,你每天给我的钱是前一天的两倍,直到满一个月(30天),百万富翁很高兴,欣然接受了这个契约。请编程序,通过计算说明,这个换钱计划对百万富翁是否是个划算的交易。
提示:(1)需要计算出30天后陌生人给了百万富翁多少钱,百万富翁给了陌生人多少钱,然后才能做出判断;(2)想要看得清楚,可以选择列出每一天,双方交易获得的钱数;(3)给出参考解答,将每天累计给对方的钱列出来,很直观。
【项目5:输出星号图】自选下面的几个图案,编程序输出(自选两个完成,其他的想想思路即可)。
先阅读例题,领会穷举法(意为“穷尽式列举”,也称枚举)的思想,然后自行选题进行解决,掌握这种程序设计的一般方法。
例题:小明有五本新书,要借给A,B,C三位小朋友,若每人每次只能借一本,则可以有多少种不同的借法?
问题分析与算法设计:本问题实际上是一个排列问题,即求从5个中取3个进行排列的方法的总数。首先对五本书从1至5进行编号,然后使用穷举的方法。假设三个人分别借这五本书中的一本,当三个人所借的书的编号都不相同时,就是满足题意的一种借阅方法。
下面是程序及其注释,要注意利用三重循环“穷举”:
#include <iostream> using namespace std; int main() { int a,b,c,count=0; cout<<"小明借书给三位小朋友书的方案有:"<<endl; for(a=1;a<=5;a++) //穷举a借5本书中的1本的全部情况 for(b=1;b<=5;b++) //穷举b借5本书中的一本的全部情况 for(c=1;c<=5;c++) //穷举c借5本书中的1本的全部情况 if(a!=b&&c!=a&&c!=b) //判断三个人借的书是否不同,(a-b)*(b-c)*(c-a)!=0更好 { ++count; cout<<count<<": "<<a<<", "<<b<<", "<<c<<endl;//输出方案 } return 0; }
任务:利用穷举的方法解决下面的问题(选做一道即算完成任务,其他可以抽时间自由安排,多做会使你更聪明。)
(1)百钱百鸡问题:中国古代数学家张丘建在他的《算经》中提出了著名的“百钱买百鸡问题”:鸡翁一,值钱五,鸡母一,值钱三,鸡雏三,值钱一,百钱买百鸡,问翁、母、雏各几何?
提示:设鸡翁、鸡母、鸡雏的个数分别为x,y,z,题意给定共100钱要买百鸡,若全买公鸡最多买20只,显然x的值在0~20之间;同理,y的取值范围在0~33之间,可得到下面的不定方程:
5x+3y+z/3=100
x+y+z=100
所以此问题可归结为求这个不定方程的整数解。
由程序设计实现不定方程的求解与手工计算不同。在分析确定方程中未知数变化范围的前提下,可通过对未知数可变范围的穷举,验证方程在什么情况下成立,从而得到相应的解。
引申:这类求解不定方程的实现,各层循环的控制变量直接与方程未知数有关,且采用对未知数的取值范围上穷举和组合的方法来复盖可能得到的全部各组解。如果要采取技巧,往往是根据题意,更合理地设置循环控制条件来减少这种穷举和组合的次数,提高程序的执行效率,需要具体问题具体分析。
(2)换分币:用一元人民币兑换成1分、2分和5分硬币,有多少种不同的兑换方法?请输出所有可能的方案。
提示:根据题意设i,j,k分别为兑换的1分、2分、5分硬币的枚数,则i,j,k的值应满足:i+j*2+k*5=100,根据取值范围构造循环解题即可。
(3)年龄几何:张三、李四、王五、刘六的年龄成一等差数列,他们四人的年龄相加是26,相乘是880,求以他们的年龄为前4项的等差数列的前20项。
提示:设数列的首项为n,项差为a,则前4项之和为n+(n+a)+(n+a+a)+(n+a+a+a)=4*n+6*a",前4 项之积为n*(n+a)*(n+a+a)*(n+a+a+a)。同时有1<=a<=4和1<=n<=6。可采用穷举法求出此数列。
(3)三色球问题:若一个口袋中放有12个球,其中有3个红的。3个白的和6个黒的,问从中任取8个共有多少种不同的颜色搭配?
提示:设任取的红球个数为i,白球个数为j,则黒球个数为8-i-j,根据题意红球和白球个数的取值范围是0~3,在红球和白球个数确定的条件下,黒球个数取值应为8-i-j<=6。
(4)委派任务:某侦察队接到一项紧急任务,要求在A、B、C、D、E、F六个队员中尽可能多地挑若干人,但有以下限制条件:
l A和B两人中至少去一人;
l A和D不能一起去;
l A、E和F三人中要派两人去;
l B和C都去或都不去;
l C和D两人中去一个;
l 若D不去,则E也不去。
问应当让哪几个人去?
提示:用a、b、c、d、e、f六个变量表示六个人是否去执行任务的状态,变量的值为1,则表示该人去;变量的值为0,则表示该人不参加执行任务,根据题意可写出表达式:
l a+b>1 //A和B两人中至少去一人;
l (a+d)!=2 //A和D不能一起去;
l a+e+f==2 // A、E、F三人中要派两人去;
l b+c==0或b+c==2 // B和C都去或都不去;
l c+d==1 //C和D两人中去一个;
l d+e==0或d==1 //若D不去,则E也不去(都不去;或D去E随便)。
上述各表达式之间的关系为“与”关系。穷举每个人去或不去的各种可能情况,代入上述表达式中进行推理运算,使上述表达式均为“真”的情况就是正确的结果。
(5)在下面的加法算式中,不同的符号代表不同的数字,相同的符号代表相同的数字。请设计程序求出"都、要、学、C"4个符号分别代表的数字。
提示:让计算机解奥数题。穷举"都、要、学、C"4个符号分别代表的数字(从0到9),然后进行组合,如果组合起来符合规则(不同的符号代表不同的数字,相同的符号代表相同的数字,且使等式成立),则为正解。
(6)警察局抓住了A、B、C、D四名盗窃嫌疑犯,其中只有一人是小偷。在审问时,A说:“我不是小偷”;B说:“C是小偷”;C说:“小偷肯定是D”;D说:“C在冤枉好人”。现在已经知道这四人中有三人说的是真话,一人说的是假话。请问到底谁是小偷?
提示:设4个变量a,b,c,d,为0时表示不是小偷,为1时表示是小偷,用四重循环穷举a,b,c,d可能的取值的组合,对每一种组合判断其是否符合题目中给出的约束。最后结论:C是小偷。
(7)有等式[※×(※3+※)]^2=8※※9,其中※处为1个数字,滴上了墨水无法辨认。请编程找出※表示哪个数字。
拓展:有等式[※×(※3○※)]^2=8※※9,其中※处为1个数字,○处为+、-、×、÷四个运算符之一,现滴上了墨水无法辨认。请编程找出※表示哪个数字,○表示哪个运算符。
【项目7-打豆豆】阅读并运行下面的程序“吃饭、睡觉、打豆豆”,体会形式上死循环,实际不“死”的技巧。在此基础上,改写程序并提交报告。
程序中用了自定义函数(第5章)。改写任务1:去除有关使用自定义函数的一切痕迹,根据用户的选择,用你已经会的cout直接输出有关内容。改写任务2:将程序中的if改为switch。
#include <iostream> using namespace std; int main() { char cChioce; void eat(); void sleep(); void hitdoudou(); do { cout<<"* 1. 吃饭"<<endl; cout<<"* 2. 睡觉"<<endl; cout<<"* 3. 打豆豆"<<endl; cout<<"* 0. 退出"<<endl; cout<<"* 请选择(0-3):"; cin>>cChioce; if (cChioce=='1') eat(); else if (cChioce=='2') sleep(); else if (cChioce=='3') hitdoudou(); else if (cChioce=='0') break; else { cout<<"\007选择错误!"<<endl<<endl; continue; } cout<<"恭喜你完成了一项工作!"<<endl<<endl; }while(1); return 0; } void eat() { cout<<"我吃吃吃... ..."<<endl; } void sleep() { cout<<"我睡觉觉... ..."<<endl; } void hitdoudou() { cout<<"我打打打... ..."<<endl; }