猴子吃桃问题。
猴子摘了一堆桃,第一天吃了一半,还嫌不过瘾,又吃了一个;第二天又吃了剩下的一半零一个;以后每天如此。
到第N天,猴子一看只剩下一个了。
问最初有多少个桃子?
cin>>n;
s=1;
for(i=2;i<=n;i++)
s=(s+1)*2;
cout<
17、文件的处理方法
#include
usingnamespacestd;
ifstreamfin(“输入文件名”);
ofstreamfout(“输出文件名”);
例:
陶陶摘苹果(文件名:
apple.cpp)【问题描述】
陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果。
苹果成熟的时候,陶陶就会跑去摘苹果。
陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。
现在已知10个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹果的数目。
假设她碰到苹果,苹果就会掉下来。
【输入文件】输入文件apple.in包括两行数据。
第一行只包括一个100到120之间(包含100和120)的整数(以厘米为单位),表示陶陶把手伸直的时候能够达到的最大高度。
第二行包含10个100到200之间(包括100和200)的整数(以厘米为单位)分别表示10个苹果到地面的高度,两个相邻的整数之间用一个空格隔开。
【输出文件】输出文件apple.out包括一行,这一行只包含一个整数,表示陶陶能够摘到的苹果的数目。
【样例输入】
110
100200150140129134167198200111
【样例输出】
5
#include
usingnamespacestd;
ifstreamfin("apple.in");
ofstreamfout("apple.out");
intmain(){
intrg,sg,i,j=0;
fin>>rg;
for(i=0;i<10;i++){
fin>>sg;
if(sg<=rg+30)j++;
}
fout<}
多重循环讲解与练习
for(;;)
{
语句组;
for(;;)
{
语句组;
}
语句组;
}
1、图形字符类
例1、输出m行n列*号
cin>>m>>n;
for(i=0;i{
for(j=0;j {
cout<<‘*’;
}
cout<}
外循环i=0时,内循环j从0一直变化到n-1,即内循环中的语句{cout<<‘*’;}被执行了n次,语句cout<当外循环的i值变化到m退出时,内循环中的语句{cout<<‘*’;}一共被执行了m×n次。
有时每列上的字符个数不同,如
例2、n=3时,输出如下图形
*
**
***
cin>>n;
for(i=0;i{
for(j=0;j<=i;j++)
{
cout<<‘*’;
}
cout<}
有时每列上的字符个数不向上面图形一般每行以1递增,如
例3、n=3时,输出如下图形
*
***
*****
cin>>n;
for(i=1;i<=n;i++)
{
for(j=1;j<=2*i-1;j++)//每行上的字符以2递增,因此是2*i
{
cout<<‘*’;
}
cout<}
如果是这样的金字塔形式
例4、n=3,输出
*
***
*****
可以看作是先输出了一个倒三角形的空格,然后再输出上例中的图形
cin>>n;
for(i=1;i<=n;i++)
{
for(j=1;j<=n-i;j++)//每行上的空格数是n-1,n-2,...,1,0这样一个递减序列,而i每次递增1,要将一个递增序列改为递减序列,直接在前面加上-号
cout<<'';
for(j=1;j<=2*i-1;j++)//每行上的字符以2递增,因此是2*i
{
cout<<‘*’;
}
cout<}
练习:
可以尝试打出如下图形:
如n=3,要求输出
***
***
***
*
***
*****
***
*
* *
*** ***
**********
* *
*** ***
***************
***
*
a
bbb
ccccc
bbb
a
2、逻辑推理题目
解逻辑判断与推理题这类题首先要把复杂的逻辑关系进行分析、抽象、化简,然后进行尝试排除,得到最后结果。
可以用计算机来验证推断的结果,复杂的还可以直接用逻辑表达式来表示各种关系条件,用计算机穷举各种可能情况,再根据条件采取累试排除或选择需要的组合。
【例1】四位同学不知是哪一位打碎了教室窗户的玻璃,老师问是哪一个同学打的。
A说:
“不是我”,B说:
“是C”,C说:
“是D”,D反驳说:
“他胡说!
”。
四个人当中只有一个人说假话,试判断哪一位打碎了教室窗户的玻璃?
分析:
用A,B,C,D分别表示这四位同学,用1表示打碎了玻璃,0表示没有打碎。
题目中四句话可表示成:
A!
=1
C==1
D==1
D!
=1
A,B,C,D只有一位同学打碎了玻璃,因此A+B+C+D的值为1。
逻辑表达式只有1和0两个值,为1表示真,为0表示假,
只有一个人说假话,则说明四个表达式的和应为3。
程序如下:
for(A=0;A<2;A++)
for(B=0;B<2;B++)
for(C=0;C<2;C++)
for(D=0;D<2;D++)if(A+B+C+D==1&&(A!
=1)+(C==1)+(D==1)+(D!
=1)==3)
{if(A==1)cout<<'A';
if(B==1)cout<<'B';
if(C==1)cout<<'C';
if(D==1)cout<<'D';
}
四个循环分别用于穷举A,B,C,D四位同学打碎玻璃和没有打碎玻璃的所有情况,加上判断就可以确定到底是谁打碎了玻璃。
也可以用其他方法来做,尝试一下。
【例2】有四个学生对我国四大淡水湖排列次序如下:
甲:
洞庭湖最大,洪泽湖最小,鄱阳湖第三。
乙:
洞庭湖最小,洪泽湖最大,鄱阳湖第二,太湖第三。
丙:
洞庭湖第三,洪泽湖最小。
丁:
洪泽湖第二,鄱阳湖最大,太湖最小。
每人都只说对了一个,试编程排出正确次序。
分析:
用d、h、p、t分别表示洞庭湖、洪泽湖、鄱阳湖、太湖。
四个湖泊的顺序号只能是1、2、3、4的不同组合,所以d+h+p+t=10。
则四个人的话可表示为:
甲:
d==1,h==4,p==3
乙:
h==1,d==4,p==2,t==3
丙:
h==4,d==3
丁:
p==1,t==4,h==2,t==3
由于每人都只说对了一个,所以上述表示每个人的观点的式子中只有一个真值为1,其他为0。
程序如下:
for(d=1;d<5;d++)
for(h=1;h<5;h++)
for(p=1;p<5;p++)
for(t=1;t<5;t++)
if((d!
=h)&&(d!
=p)&&(d!
=t)&&
(h!
=p)&&(h!
=t)&&(p!
=t)&&
(d==1)+(h==4)+(p==3)==1&&
(d==4)+(h==1)+(p==2)+(t==3)==1&&
(d==3)+(h==4)==1&&
(h==2)+(p==1)+(t==4)==1)
{cout<<"dongtinghuis:
"<cout<<"hongzehuis:
"<cout<<"poyanghuis:
"<
cout<<"taihuis:
"<}
程序写得稍嫌复杂,实际上可以简便一些。
for(d=1;d<5;d++)
for(h=1;h<5;h++)
if(d!
=h)
for(p=1;p<5;p++)
if(p!
=h&&p!
=d)
{t=10-d-h-p;
if((d==1)+(h==4)+(p==3)==1)
if((d==4)+(h==1)+(p==2)+(t==3)==1)
if((d==3)+(h==4)==1)
if((h==2)+(p==1)+(t==4)==1)
{cout<<"dongtinghuis:
"<cout<<"hongzehuis:
"<cout<<"poyanghuis:
"<
cout<<"taihuis:
"<}
}
循环减少一个,表达式分开写,看起来要清晰些。
练习:
(1)某年级数学竞赛中,A、B、C、D、E五位同学获得前五名。
A说:
“D是第一,C是第四”;B说:
“A是第一,E是第二”;C说:
“B是第二,D是第三”;D说:
“E是第三,A是第五”;E说:
“E是第二,C是第四”。
每人都只说对了一个,试编程排出正确次序。
(2)甲、乙、丙三位同学中有一人趁大家不在教室的时候把教室打扫干净了。
事后老师问是谁做的好事。
甲说:
“是乙做的”,乙说:
“不是我”,丙说:
“不是我”。
三个人当中只有一个人说真话,试判断哪一位做了好事?
(3)有红、黄、蓝、白四色球各一个,放置在编号为1、2、3、4四个格子的盒中,每个格子中只能放一个小球,他们的顺序不知。
甲、乙、丙三人猜测的顺序如下:
甲说:
蓝色球编号为1,黄色球编号为2;乙说:
蓝色球编号为2,白色球编号为3;丙说:
红色球编号为2,白色球编号为4。
结果证明三个人各猜中一半。
问四个格子的盒中放置小球情况。
一维数组讲解与练习
一、为什么要使用数组
学到现在,我们用分支结构解决了计算机的智能判断问题,用循环充分利用了计算机处理速度快的特点,也可以用循环对大量数据进行处理,但这些数据却无法大量保存,在这点上还没有利用上计算机存储容量大的特点。
在程序语言中有一种数据结构可以解决这个问题,那就是数组。
例1、输入1000个学生的某门课程的成绩,打印出低于平均分的同学号数与成绩。
分析:
在解决这个问题时,虽然可以通过读入一个数就累加一个数的办法来求学生的总分,进而求出平均分。
但因为只有读入最后一个学生的分数以后才能求得平均分,且要打印出低于平均分的同学,故必须把1000个学生的成绩都保留下来,然后逐个和平均分比较,把高于平均分的成绩打印出来。
如果,用简单变量a1,a2,…,a1000存放这些数据,可想而知程序要很长且繁。
要想如数学中使用下标变量ai形式表示这1000个数,则可以引入下标变量a[i]。
这样问题的程序可写为:
tot=0;//tot表示总分
for(i=1;i<=1000;i++)//环读入每一个学生的成绩,并累加它到总分}
{
cin>>a[i];
tot:
=tot+a[i];
}
ave=tot/1000;//计算平均分
for(i=1;i<=1000;i++)
if(a[i]'<而要在程序中使用下标变量,则必须先说明这些下标变量的整体——数组,即数组是若干个同名(如上面的下标变量的名字都为a)下标变量的集合。
二、一维数组
1、一维数组的定义和引用
当数组中每个元素只带有一个下标时,我们称这样的数组为一维数组。
数组是同一类型的一组值(10个char、15个int…),在内存中顺序存放。
整个数组共用一个名字,而其中的每一项又称为一个元素。
1)定义方式:
类型说明符 数组名[常量表达式];
int a[4]; //int是数组元素的类型说明,4表示元素个数,a表示数组名称,整个说明表明a数组由4个int型元素组成,这四个元素分别是:
a[0],a[1],a[2],a[3]
要注意的两个地方:
其序号从0开始,而不是从1开始。
所以inta[4];实际上不包含a[4]这个元素
C++不允许对数组的大小作动态的定义,即数组的大小不能是变量,必须是常量。
即不能定义为inta[n];只能是inta[1000];等,即元素个数必须是确定的。
2)一维数组元素的引用
数组必须先定义,具体引用时(赋值、运算、输出)其元素等同于变量。
数组元素的赋值与输出通常采用的是循环。
例2、输入100个数,将其倒序输出。
intmain()
{ int i, a[100];
for(i=0;i<100;i++)
cin>>a[i];
for(i=99;i>=0;i--)
cout<}
3)一维数组的初始化
除了用循环读入处理外,一维数组还可以直接进行赋值操作。
inta,b=0,c[5]={1,2,3,4,5};
此例也可以写成,intc[5];c[0]=1;c[1]=2;c[2]=3;c[3]=4;c[4]=5;
注意:
不能给数组整体赋值,只能一个一个地赋值
比如上例写成:
inta,b=0,c[5]={1,2,…,5};就是错误的。
2、一位数组的应用实例
例3、求Fibonacci数列:
1,1,2,3,5,8,......的前20个数,将它们5个数一行的输出,每两个数之间隔一个制表符的距离。
分析:
Fibonacci数列可表示为以下数学递推公式:
F1=1 (n=1)
F2=1 (n=2)
Fn=Fn-1+Fn-2 (n>=3)
intmain()
{ int i;
int f[21];
f[1]=1;
f[2]=1;
for(i=2;i<21;i++)
f[i]=f[i-1]+f[i-2];
for(i=1;i<21;i++)
{
cout<if(i%5==0) cout<<“\n”;
}
}
例4、输入十个正整数,把这十个数按由大到小的顺序排列。
将数据按一定顺序排列称为排序,排序的算法有很多,其中选择排序是一种较简单的方法。
分析:
要把十个数按从大到小顺序排列,则排完后,第一个数最大,第二个数次大,……。
因此,我们第一步可将第