CC++语言经典实用趣味程序设计编程百例精解2.docx

上传人:b****6 文档编号:7953711 上传时间:2023-01-27 格式:DOCX 页数:100 大小:74.04KB
下载 相关 举报
CC++语言经典实用趣味程序设计编程百例精解2.docx_第1页
第1页 / 共100页
CC++语言经典实用趣味程序设计编程百例精解2.docx_第2页
第2页 / 共100页
CC++语言经典实用趣味程序设计编程百例精解2.docx_第3页
第3页 / 共100页
CC++语言经典实用趣味程序设计编程百例精解2.docx_第4页
第4页 / 共100页
CC++语言经典实用趣味程序设计编程百例精解2.docx_第5页
第5页 / 共100页
点击查看更多>>
下载资源
资源描述

CC++语言经典实用趣味程序设计编程百例精解2.docx

《CC++语言经典实用趣味程序设计编程百例精解2.docx》由会员分享,可在线阅读,更多相关《CC++语言经典实用趣味程序设计编程百例精解2.docx(100页珍藏版)》请在冰豆网上搜索。

CC++语言经典实用趣味程序设计编程百例精解2.docx

CC++语言经典实用趣味程序设计编程百例精解2

C/C++语言经典、实用、趣味程序设计编程百例精解

(2)

51.谁是窃贼

52.黑与白

53.迷语博士的难题

(1)

54.迷语博士的难题

(2)

55.哪个大夫哪天值班

56.区分旅客国籍

57.谁家孩子跑最慢

58.拉丁方阵

59.填表格

60.1~9分成1:

2:

3的三个3位数

61.1~9组成三个3位的平方数

62.由8个整数形成奇特的立方体

63.减式还原

64.乘式还原

65.乘式还原

(2)

66.除式还原

(1)

67.除式还原

(2)

68.九位累进可除数

69.魔术师的猜牌术

(1)

70.魔术师的猜牌术

(2)

71.约瑟夫问题

72.邮票组合

73.和数能表示1~23的5个正整数

74.可称1~40磅的4块砝码

75.10个小孩分糖果

76.小明买书

77.波松瓦酒的分酒趣题

78.求π的近似值

79.求π的近似值

(2)

80.奇数平方的一个有趣性质

81.角谷猜想

82.四方定理

83.卡布列克常数

84.尼科彻斯定理

85.回文数的形成

86.自动发牌

87.黑白子交换

88.常胜将军

89.抢30

90.搬山游戏

91.人机猜数游戏

92.人机猜数游戏

(2)

93.汉诺塔

94.兎子产子

95.将阿拉伯数字转换为罗马数字

96.选美比赛

97.满足特异条件的数列

98.八皇后问题

99.超长正整数的加法

100.数字移动

51.谁是窃贼

公安人员审问四名窃贼嫌疑犯。

已知,这四人当中仅有一名是窃贼,还知道这四人中每人要么是诚实的,要么总是说谎的。

在回答公安人员的问题中:

甲说:

“乙没有偷,是丁偷的。

乙说:

“我没有偷,是丙便的。

丙说:

“甲没有偷,是乙偷的。

丁说:

“我没有偷。

请根据这四人的答话判断谁是盗窃者。

*问题分析与算法设计

假设A、B、C、D分别代表四个人,变量的值为1代表该人是窃贼。

由题目已知:

四人中仅有一名是窃贼,且这四个人中的每个人要么说真话,要么说假话,而由于甲、乙、丙三人都说了两句话:

“X没偷,X偷了”,故不论该人是否说谎,他提到的两人中必有一人是小偷。

故在列条件表达式时,可以不关心谁说谎,谁说实话。

这样,可以列出下列条件表达式:

甲说:

”乙没有偷,是丁偷的。

”B+D=1

乙说:

“我没有偷,是丙偷有。

”B+C=1

丙说:

“甲没有偷,是乙偷的。

”A+B=1

丁说:

“我没有偷。

”A+B+C+D=1

其中丁只说了一句话,无法判定其真假,表达式反映了四人中仅有一名是窃贼的条件。

*程序说明与注释

#include

intmain()

{

inti,j,a[4];

for(i=0;i<4;i++)/*假定只有第i个人为窃贼*/

{

for(j=0;j<4;j++)/*将第i个人设置为1表示窃贼,其余为0*/

if(j==i)a[j]=1;

elsea[j]=0;

if(a[3]+a[1]==1&&a[1]+a[2]==1&&a[0]+a[1]==1)/*判断条件是否成立*/

{

printf("Thethiefis");/*成立*/

for(j=0;j<=3;j++)/*输出计算结果*/

if(a[j])printf("%c.",j+'A');

printf("\n");

}

}

}

*运行结果

ThethiefisB.(乙为窃贼。

52.黑与白

有A、B、C、D、E五人,每人额头上都帖了一张黑或白的纸。

五人对坐,每人都可以看到其它人额头上的纸的颜色。

五人相互观察后,

A说:

“我看见有三人额头上帖的是白纸,一人额头上帖的是黑纸。

B说:

“我看见其它四人额头上帖的都是黑纸。

C说:

“我看见一人额头上帖的是白纸,其它三人额头上帖的是黑纸。

D说:

“我看见四人额头上帖的都是白纸。

E什么也没说。

现在已知额头上帖黑纸的人说的都是谎话,额头帖白纸的人说的都是实话。

问这五人谁的额头是帖白纸,谁的额头是帖黑纸?

*问题分析与算法设计

假如变量A、B、C、D、E表示每个人额头上所帖纸的颜色,0代表是黑色,1代表是白色。

根据题目中A、B、C、D四人所说的话可以总结出下列关系:

A说:

a&&b+c+d+e==3||!

a&&b+c+d+e!

=3

B说:

b&&a+c+d+e==0||!

b&&a+c+d+e!

=0

C说:

c&&a+b+d+e==1||!

c&&a+b+d+e!

=1

D说:

d&&a+b+c+e==4||!

d&&a+b+c+e!

=4

穷举每个人额头所帖纸的颜色的所有可能的情况,代入上述表达式中进行推理运算,使上述表达式为“真”的情况就是正确的结果。

*程序说明与注释

#include

intmain()

{

inta,b,c,d,e;

for(a=0;a<=1;a++)/*黑色:

0白色:

1*/

for(b=0;b<=1;b++)/*穷举五个人额头帖纸的全部可能*/

for(c=0;c<=1;c++)

for(d=0;d<=1;d++)

for(e=0;e<=1;e++)

if((a&&b+c+d+e==3||!

a&&b+c+d+e!

=3)

&&(b&&a+c+d+e==0||!

b&&a+c+d+e!

=0)

&&(c&&a+b+d+e==1||!

c&&a+b+d+e!

=1)

&&(d&&a+b+c+e==4||!

d&&a+b+c+e!

=4))

{

printf("Aispastedapieceof%spaperonhisforehead.\n",

a?

"white":

"black");

printf("Bispastedapieceof%spaperonhisforehead.\n",

b?

"white":

"black");

printf("Cispastedapieceof%spaperonhisforehead.\n",

c?

"white":

"black");

printf("Dispastedapieceof%spaperonhisforehead.\n",

d?

"white":

"black");

printf("Eispastedapieceof%spaperonhisforehead.\n",

e?

"white":

"black");

}

}

*运行结果

Aispastedapaperofblackpaperonhisforehead.(黑)

Bispastedapaperofblackpaperonhisforehead.(黑)

Cispastedapaperofwhitepaperonhisforehead.(白)

Dispastedapaperofblackpaperonhisforehead.(黑)

Eispastedapaperofwhitepaperonhisforehead.(白)

53.迷语博士的难题

(1)

诚实族和说谎族是来自两个荒岛的不同民族,诚实族的人永远说真话,而说谎族的人永远说假话。

迷语博士是个聪明的人,他要来判断所遇到的人是来自哪个民族的。

迷语博士遇到三个人,知道他们可能是来自诚实族或说谎族的。

为了调查这三个人是什么族的,博士分别问了他们的问题,这是他们的对话:

问第一个人:

“你们是什么族?

”,答:

“我们之中有两个来自诚实族。

”第二个人说:

“不要胡说,我们三个人中只有一个是诚实族的。

”第三个人听了第二个人的话后说:

“对,就是只有一个诚实族的。

请根据他的回答判断他们分别是哪个族的。

*问题分析与算法设计

假设这三个人分别为A、B、C,若说谎其值为0,若诚实,其值为1。

根据题目中三个人的话可分别列出:

第一个人:

a&&a+b+c==2||!

a&&a+b+c!

=2

第二个人:

b&&a+b+c==1||!

b&&a+b+c!

=1

第三个人:

c&&a+b+c==1||!

c&&a+b+c!

=1

利用穷举法,可以很容易地推出结果。

*程序说明与注释

#include

intmain()

{

inta,b,c;

for(a=0;a<=1;a++)/*穷举每个人是说谎还是诚实的全部情况*/

for(b=0;b<=1;b++)/*说谎:

0诚实:

1*/

for(c=0;c<=1;c++)

if((a&&a+b+c==2||!

a&&a+b+c!

=2)/*判断是否满足题意*/

&&(b&&a+b+c==1||!

b&&a+b+c!

=1)

&&(c&&a+b+c==1||!

c&&a+b+c!

=1))

{

printf("Aisa%s.\n",a?

"honest":

"lier");/*输出判断结果*/

printf("Bisa%s.\n",b?

"honest":

"lier");

printf("Cisa%s.\n",c?

"honest":

"lier");

}

}

*运行结果

Aisalier(说谎族)

Bisalier(说谎族)

Cisalier(说谎族)

*思考题

迷语博士遇到四个人,知道他们可能是来自诚实族和说谎族的。

为了调查这四个人是什么族的,博士照例进行询问:

”你们是什么族的?

第一人说:

”我们四人全都是说谎族的。

第二人说:

”我们之中只有一人是说谎族的。

第三人说:

”我们四人中有两个是说谎族的。

第四人说:

”我是诚实族的。

问自称是“诚实族”的第四个人是否真是诚实族的?

(答案:

第四个人是诚实族的。

54.迷语博士的难题

(2)

两面族是荒岛上的一个新民族,他们的特点是说话真一句假一句且真假交替。

如果第一句为真,则第二句是假的;如果第一句为假的,则第二句就是真的,但是第一句是真是假没有规律。

迷语博士遇到三个人,知道他们分别来自三个不同的民族:

诚实族、说谎族和两面族。

三人并肩站在博士前面。

博士问左边的人:

“中间的人是什么族的?

”,左边的人回答:

“诚实族的”。

博士问中间的人:

“你是什么族的?

”,中间的人回答:

“两面族的”。

博士问右边的人:

“中间的人究竟是什么族的?

”,右边的人回答:

“说谎族的”。

请问:

这三个人都是哪个民族的?

*问题分析与算法设计

这个问题是两面族问题中最基本的问题,它比前面只有诚实族和说谎族的问题要复杂。

解题时要使用变量将这三个民族分别表示出来。

令:

变量A=1表示:

左边的人是诚实族的(用C语言表示为A);

变量B=1表示:

中间的人是诚实族的(用C语言表示为B);

变量C=1表示:

右边的人是诚实族的(用C语言表示为C);

变量AA=1表示:

左边的人是两面族的(用C语言表示为AA);

变量BB=1表示:

中间的人是两面族的(用C语言表示为BB);

变量CC=1表示:

右边的人是两面族的(用C语言表示为CC);

则左边的人是说谎族可以表示为:

A!

=1且AA!

=1(不是诚实族和两面族的人)

用C语言表示为:

!

A&&!

AA

中间的人是说谎族可以表示为:

B!

=1且BB!

=1

用C语言表示为:

!

B&&!

BB

右边的人是说谎族可以表示为:

C!

=0且CC!

=1

用C语言表示为:

!

C&&!

CC

根据题目中“三人来自三个民族”的条件,可以列出:

a+aa!

=2&&b+bb!

=2&&c+cc!

=2且a+b+c==1&&aa+bb+cc==1

根据左边人的回答可以推出:

若他们是诚实族,则中间的人也是诚实族;若他不是诚实族,则中间的人也不是诚实族。

以上条件可以表示为:

c&&!

b&&!

bb||(!

c&&!

cc)&&(b||bb)||!

c&&cc

将全部逻辑条件联合在一起,利用穷举的方法求解,凡是使上述条件同时成立的变量取值就是题目的答案。

*程序说明与注释

#include

intmain()

{

inta,b,c,aa,bb,cc;

for(a=0;a<=1;a++)/*穷举全部情况*/

for(b=0;b<=1;b++)

for(c=0;c<=1;c++)

for(aa=0;aa<=1;aa++)

for(bb=0;bb<=1;bb++)

for(cc=0;cc<=1;cc++)

if(a+aa!

=2&&b+bb!

=2&&c+cc!

=2&&/*判断逻辑条件*/

a+b+c==1&&aa+bb+cc==1&&

(a&&!

aa&&b&&!

bb||!

a&&!

b)&&

!

b&&

(c&&!

b&&!

bb||(!

c&&!

cc)&&(b||bb)||!

c&cc))

{

printf("Themanstandonleftisa%s.\n",

aa?

"double--dealer":

(a?

"honest":

"lier"));

printf("Themanstandonleftisa%s.\n",

bb?

"double--dealer":

(b?

"honest":

"lier"));

printf("Themanstandonleftisa%s.\n",

cc?

"double--dealer":

(c?

"honest":

"lier"));

/*输出最终的推理结果*/

}

}

*运行结果

Themanstandonleftisadouble--dealer.(左边的人是两面族的)

Themanstandoncenterisalier.(中间的人是说谎族的)

Themanstandonrightisahonest.(右边的人是诚实族的)

*思考题

迷语博士遇到三个人,便问第一个人:

“你是什么族的?

”,回答:

“诚实族的。

”问第二个人:

“你是什么族的?

”,答:

“说谎族的。

”博士又问第二个人:

“第一个人真的是诚实族的吗?

”,答:

“是的。

”问第三个人:

“你是什么族的?

”,答:

“诚实族的。

”博士又问第三个人:

“第一个人是什么族的?

”,答:

“两面族的。

请判断这个人到底是哪个民族的?

(答案:

第一个人是诚实族的,第二个人是两面族的,第三人是说谎族。

55.哪个大夫哪天值班

医院有A、B、C、D、E、F、G七位大夫,在一星期内(星期一至星期天)每人要轮流值班一天。

现在已知:

A大夫比C大夫晚一天值班;

D大夫比E大夫晚二天值班;

B大夫比G大夫早三天值班;

F大夫的值班日在B和C大夫的中间,且是星期四;

请确定每天究竟是哪位大夫值班?

*问题分析与算法设计

由题目可推出如下已知条件:

*F是星期四值班;

*B值班的日期在星期一至星期三,且三天后是G值班;

*C值班的日期在星期五至星期六,且一天后是A值班;

*E两天后是D值班;E值班的日期只能在星期一至星期三;

在编程时用数组元素的下标1到7表示星期一到星期天,用数组元素的值分别表示A~F七位大夫。

*程序说明与注释

#include

#include

inta[8];

char*day[]={"","MONDAY","TUESDAY","WEDNESDAY","THURSDAYT",

"FRIDAY","SATUDAY","SUNDAY"};/*建立星期表*/

intmain()

{

inti,j,t;

a[4]=6;/*星期四是F值班*/

for(i=1;i<=3;i++)

{

a[i]=2;/*假设B值班的日期*/

if(!

a[i+3])a[i+3]=7;/*若三天后无人值班则安排G值班*/

else{a[i]=0;continue;}/*否则B值班的日期不断对*/

for(t=1;t<=3;t++)/*假设E值班的时间*/

{

if(!

a[t])a[t]=5;/*若当天无人值班则安排E值班*/

elsecontinue;

if(!

a[t+2])a[t+2]=4;/*若E值班两天后无人值班则应为D*/

else{a[t]=0;continue;}/*否则E值班的日期不对*/

for(j=5;j<7;j++)

{

if(!

a[j])a[j]=3;/*若当天无人值班,则安排C值班*/

elsecontinue;

if(!

a[j+1])a[j+1]=1;/*C之后一天无人值班则应当是A值班*/

else{a[j]=0;continue;}/*否则A值班日期不对*/

for(i=1;i<=7;i++)/*安排完毕,输出结果*/

printf("Doctor%cisonduty%s.\n",'A'+a[i]-1,day[i]);

exit(0);

}

}

}

}

*运行结果

DoctorEisondutyMONDAY.(星期一:

E)

DoctorBisondutyTUESDAY.(星期二:

B)

DoctorDisondutyWEDNESDAY.(星期三:

D)

DoctorFisondutyTHUESDAY.(星期四:

F)

DoctorGisondutyFRIDAY.(星期五:

G)

DoctorCisondutySATURDAY.(星期六:

C)

DoctorAisondutySUNDAY.(星期日:

A)

*思考题

在本题的求解过程中,我们只考虑了一星期之内的情况,没有考虑跨周的情况。

对于“B大夫比G大夫早三天值班的”条件只是简单的认为是在同一周内早三天。

若考虑跨周的情况就可能出现:

B大夫星期一值班,而G大夫是上周的星期五。

同样,对“F大夫的值班日在B和C大夫的中间”这个条件,也可以扩展为:

“只要F大夫的值班日在B和C大夫的中间就可以”。

请考虑允许跨周的情况下,可能的时间安排表。

56.区分旅客国籍

在一个旅馆中住着六个不同国籍的人,他们分别来自美国、德国、英国、法国、俄罗斯和意大利。

他们的名字叫A、B、C、D、E和F。

名字的顺序与上面的国籍不一定是相互对应的。

现在已知:

1)A美国人是医生。

2)E和俄罗斯人是技师。

3)C和德国人是技师。

4)B和F曾经当过兵,而德国人从未参过军。

5)法国人比A年龄大;意大利人比C年龄大。

6)B同美国人下周要去西安旅行,而C同法国人下周要去杭州度假。

试问由上述已知条件,A、B、C、D、E和F各是哪国人?

*问题分析与算法设计

首先进行题目分析,尽可能利用已知条件,确定谁不是哪国人。

由:

1)2)3)可知:

A不是美国人,E不是俄罗斯人,C不是德国人。

另外因为A与德国人的职业不同,E与美、德人的职业不同,C与美、俄人的职业不同,故A不是俄罗斯人或德国人,E不是美国人或德国人,C不是美国人或俄罗斯人。

由4)和5)可知B和F不是德国人,A不是法国人,C不是意大利人。

由6)可知B不是美国人,也不是法国人(因B与法国人下周的旅行地点不同);C不是法国人。

将以上结果汇总可以得到下列条件矩阵:

.美(医生)英法德(技师)意大利俄(教师)

A(医生)X.XX.X

BX.XX..

C(技师)X.XXXX

D......

E(教师)X..X.X

F...X..

根据此表使用消元法进行求解,可以方便地得到问题的答案。

将条件矩阵输入计算机,用程序实现消去算法是很容易的。

*程序说明与注释

#include

char*m[7]={"","U.S","U.K","FRANCE","GER","ITALI","EUSSIAN"};/*国名*/

intmain()

{

inta[7][7],i,j,t,e,x,y;

for(i=0;i<7;i++)/*初始化条件矩阵*/

for(j=0;j<7;j++)/*行为人,列为国家,元素的值表示某人是该国人*/

a[i][j]=j;

for(i=1;i<7;i++)/*条件矩阵每一列的第0号元素作为该列数据处理的标记*/

a[0][i]=1;/*标记该列尚未处理*/

a[1][1]=a[2][1]=a[3][1]=a[5][1]=0;/*输入条件矩阵中的各种条件*/

a[1][3]=a[2][3]=a[3][3]=0;/*0表示不是该国的人*/

a[1][4]=a[2][4]=a[3][4]=a[5][4]=a[6][4]=0;

a[3][5]=0;

a[1][6]=a[3][6]=a[5][6]=0;

while(a[0][1]+a[0][2]+a[0][3]+a[0][4]+a[0][5]+a[0][6]>0)

{/*当所有六列均处理完毕后退出循环*/

for(i=1;i<7;i++)/*i:

列坐标*/

if(a[0][i])/*若该列尚未处理,则进行处理*/

{

for(e=0,j=1;j<7;j++)/*j:

行坐标e:

该列中非0元素计数器*/

if(a[j][i]){x=j;y=i;e++;}

if(e==1)/*若该列只有一个元素为非零,则进行消去操作*/

{

for(t=1;t<7;t++)

if(t!

=i)a[x][t]=0;/*将非零元素所在的行的其它元素置0*/

a[0][y]=0;/*设置该列已处理完毕的标记*/

}

}

}

for(i=1;i<7;i++)/*输出推理结果*/

{

printf("%ciscomingfrom",'A'-1+i);

for(j=1;j<7;j++)

if(a[i][j]!

=0)

{printf("%s.\n",m[a[i][j>);break;}

}

}

*运行结果

AiscomingfromITALY.(意大利人)

BiscomingfromEUSSIAN.(俄罗斯人)

CiscomingfromU.K..(英国人)

DiscomingfromGER.(德国人)

EiscomingfromFRANCE.(法国人)

FiscomingfromU.S..(美国人)

*问题的进一步讨论

生成条件矩阵然后使用消去法进行推理判断是一种常用的方法。

对于解决较为复杂的逻辑问题是十分有效的。

*思考题

地理课上老师给出一张没有说明省份的中国地图,从中选出五个省从1到5编号,要大家写出省份的名称。

交卷后五位同学每人只答了二个省份的名称如下,且每人只答对了一个省,问正确答案是什么?

A答:

2号陕西,5号甘肃B答:

2号湖北,4号山东

C答:

1号山东,5号吉林D答:

3号湖北,4号吉林

E答:

2号甘肃,3号陕西

57.谁家孩子跑最慢

张王李三家各有三个小孩。

一天,三家的九个孩子在一起比赛短跑,规定不分年龄大小,跑第一得9分,跑第2得8分,依此类推。

比赛结果各家的总分相同,且这些孩子没有同时到达终点的,也没有一家的两个或三个孩子获得相连的名次。

已知获第一名的是李家的孩子,获得第二的是王家的孩子。

问获得最后一名的是谁家的孩子?

*问题分析与算法设计

按题目的条件,共有1+2+3+...+9=45分,每家的孩子的得分应为15分。

根据题意可知

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1