课程设计
- 一、
题目:有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法?
输入数据首先包含一个整数N,表示测试实例的个数,然后是N行数据,每行包含一个整数M(1<=M<=40),表示楼梯的级数。
解题思路:看到题目后首先想到这个肯定不是,一点一点总结。可以根据排列组合的方式总结出规律:
a[i]=a[i-1]+a[i-2];
剩下就可以for循环完成。
*注意到有多组测试数据,可以用一个数组先将范围内的值储存下来。可以优化。
*需要找出前几项。
题目代码:
#include<iostream>
using namespace std;
int a[42];
int main()
{
int i,n,m;
a[2]=1;
a[3]=2;
for(i=4;i<41;i++)
a[i]=a[i-1]+a[i-2];
while(cin>>n)
{
for(i=0;i<n;i++)
{
cin>>m;
cout<<a[m]<<endl;
}
}
}
题目:有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行。请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数。
其中,蜂房的结构如下所示。
1 3 5 7 9 11......
2 4 6 8 10 12......
解题思路:注意到此题目其实和上一道题是一种类型的题目,只是描述不同,本质上是一样的。比如:1可以到2和3,实际上和上题跨一阶或两阶台阶是一样的。
(遇到这种情况告诉我们一定要仔细审题,看到题目的本质)
题目代码:
#include<iostream>
using namespace std;
long long c[51];
int main()
{
int i,n,a,b;
c[0]=0;
c[1]=1;
c[2]=2;
for(i=3;i<51;i++)
c[i]=c[i-1]+c[i-2];
while(cin>>n)
{
for(i=0;i<n;i++)
{
cin>>a>>b;
cout<<c[b-a]<<endl;
}
}
return 0;
}
- 二、
题目:“水仙花数”是指一个三位数,它的各位数字的立方和等于其本身,比如:153=1^3+5^3+3^3。
现在要求输出所有在m和n范围内的水仙花数。
解题思路:该题主要是要将数的每位上的数表示出来,该题说该数只可能是三位数,所以可以用简单的方式将个位十位百位的数分别表示。
*但是遇到未知位数的数时可以考虑应用循环。
题目代码:
#include<iostream>
using namespace std;
int m[1005],n[1005],a[1000];
int main()
{
int i,j,o,x,y,z,p=0;
i=0;
while(cin>>m[i]>>n[i])
i++;
o=i;
for(i=0;i<o;i++)
{
p=0;
for(j=m[i];j<=n[i];j++)
{
y=j%100;
x=j/100;
y=y/10;
z=j%10;
if(j==x*x*x+y*y*y+z*z*z)
{
a[p]=j;
p++;
}
}
if(p==0) cout<<"no";
for(int g=0;g<p;g++)
{
if(p!=0&&g!=p-1) cout<<a[g]<<" ";
if(p!=0&&g==p-1) cout<<a[g];
a[g]=0;
}
cout<<endl;
}
}
- 三、
题目:多项式的描述如下:
1 - 1/2 + 1/3 - 1/4 + 1/5 - 1/6 + ...
现在请你求出该多项式的前n项的和。
解题思路:
可以总结出公式
n为奇数时:1/n
n为偶数时:-1/n
然后就可以根据公式应用for循环就可得出。
*注意输出结果是小数,过程中间1/n时也应注意整数和小数的转换。
题目代码:
#include<iostream>
#include<stdio.h>
using namespace std;
int n[105];
int main()
{
int i,j,m;
double x,y;
cin>>m;
for(i=0;i<m;i++)
cin>>n[i];
for(i=0;i<m;i++)
{
x=0;
for(j=0;j<n[i];j++)
{
if((j+1)%2==0) y=(-1);
else y=1;
x=x+y*(1.0/(j+1));
}
printf("%.2f",x);
cout<<endl;
}
}
- 四、
题目:青年歌手大奖赛中,评委会给参赛选手打分。选手得分规则为去掉一个最高分和一个最低分,然后计算平均得分,请编程输出某选手的得分。
输入数据有多组,每组占一行,每行的第一个数是n(2<n<=100),表示评委的人数,然后是n个评委的打分。
解题思路:
应该先将每一组数据排序,再去掉最大值最小值。
*注意:去掉最大值、最小值后,该组数据不是原来的数目,应该减二。
*注意:保留两位小数。
题目代码
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int n[105],a[105][105];
int main()
{
int i=0,j,x,m;
double y;
while(cin>>n[i])
{
for(j=0;j<n[i];j++)
cin>>a[i][j];
i++;
}
m=i;
for(i=0;i<m;i++)
{
sort(a[i],a[i]+n[i]);
x=0;
for(j=1;j<n[i]-1;j++)
x=x+a[i][j];
y=x/(n[i]-2.0);
printf("%.2f",y);
cout<<endl;
}
}
- 五、
题目:
有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?
输入数据由多个测试实例组成,每个测试实例占一行,包括一个整数n(0<n<55),n的含义如题目中描述。
n=0表示输入数据的结束,不做处理。
解题思路:
可以找出规律:
该年的牛的数量=原来有的(去年的数量)+出生的(四年前的牛的数量)
*可以应用数组将其提前储存起来
即为:a[i]=a[i-1]+a[i-3]
*注意要将前几项单独讨论
题目代码:
#include<iostream>
using namespace std;
int a[57];
int main()
{
int i=0,n;
a[1]=1,a[2]=2,a[3]=3,a[4]=4;
for(i=4;i<57;i++)
a[i]=a[i-1]+a[i-3];
while(cin>>n)
{
if(n==0) break;
cout<<a[n]<<endl;
}
}
- 六、
题目:
输入n(n<=100)个整数,按照绝对值从大到小排序后输出。题目保证对于每一个测试实例,所有的数的绝对值都不相等。
解题思路:
该题目一是要取绝对值,二是要排序,排序后输出原来的数。所以可以考虑应用两个数组,一组储存原来的数,一组储存取绝对值后的数。再将原来的数对应输出即可。
*注意输出原来的数。
*将绝对值与原来的数对应可以再次取绝对值(题目中保证绝对值均不相等)
题目代码:
#include<iostream>
#include<algorithm>
using namespace std;
int n[105],a[105][105],b[105][105];
int main()
{
int i=0,m,o,j;
while(cin>>n[i])
{
for(j=0;j<n[i];j++)
{
cin>>a[i][j];
if(a[i][j]<0) b[i][j]=-a[i][j];
else b[i][j]=a[i][j];
}
if(n[i]==0) break;
i++;
}
m=i;
for(i=0;i<m;i++)
{
sort(b[i],b[i]+n[i]);
for(o=n[i]-1;o>=0;o--)
{for(j=0;j<n[i];j++)
{
if(a[i][j]==b[i][o]||a[i][j]==-b[i][o])
{
if(o!=0)
cout<<a[i][j]<<" ";
else cout<<a[i][j];
}
}}
cout<<endl;
}
}
- 七、
题目:
有n(n<=100)个整数,已经按照从小到大顺序排列好,现在另外给一个整数x,请将该数插入到序列中,并使新的序列仍然有序。
解题思路:
排序问题,可以直接应用排序函数。
*注意:sort(a,a+n);在#include<algorithm>里
*可以将x储存在a[n]
题目代码:
#include<iostream>
#include<algorithm>
using namespace std;
int n[105],a[105][105],m[105];
int main()
{
int i=0,j,t;
while(cin>>n[i])
{
cin>>m[i];
if(n[i]==0&&m[i]==0) break;
for(j=0;j<n[i];j++)
cin>>a[i][j];
i++;
}
t=i;
for(i=0;i<t;i++)
{
a[i][n[i]]=m[i];
sort(a[i],a[i]+n[i]+1);
for(j=0;j<=n[i];j++)
{
if(j==n[i]) cout<<a[i][j];
else cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
- 八、
题目:
如果每个老师的工资额都知道,最少需要准备多少张人民币,才能在给每位老师发工资的时候都不用老师找零呢?
这里假设老师的工资都是正整数,单位元,人民币一共有100元、50元、10元、5元、2元和1元六种。
解题思路:
注意到从大面额到小面额就为需要人民币最少的情况。所以,可以利用整数相除为整数来计算需要该种面额数。而取余后即可得到剩下的钱数。
*注意:还应考虑:前边的是否已经将其工资全部付完。
题目代码:
#include<stdio.h>
int main()
{
int a[100],n,i,sum;
while (scanf("%d",&n)!=EOF)
{
if (n==0) break;
for (i=0,sum=0;i<n;i++)
{
scanf("%d",&a[i]);
do
{
if (a[i]>=100) {sum+=1;a[i]-=100;}
else if (a[i]>=50) {sum+=1;a[i]-=50;}
else if (a[i]>=10) {sum+=1;a[i]-=10;}
else if (a[i]>=5) {sum+=1;a[i]-=5;}
else if (a[i]>=2) {sum+=1;a[i]-=2;}
else if (a[i]==1) {sum+=1;a[i]-=1;}
}while (a[i]!=0);
}
printf("%d\n",sum);
}
}
- 九、
题目:
“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。请写一个程序判断读入的字符串是否是“回文”。
解题思路:
可以将其看作为一个字符串,应用字符串与字符数组的关系判断正反向是否相同。
*注意:输入字符串可以考虑用gets,并注意gets的头文件#include<string.h>
题目代码:
#include<iostream>
#include<string.h>
using namespace std;
char a[105][105];
int main()
{
int i,n,x,j,t=0;
cin>>n;
for(i=0;i<=n;i++)
{
gets(a[i]);
}
for(i=1;i<=n;i++)
{
x=strlen(a[i]);
t=0;
for(j=0;j<x;j++)
{
if(a[i][j]!=a[i][x-j-1]) t=1;
}
if(t==0) cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
}
- 十、
题目:
输入一个十进制数N,将它转换成R进制数输出。
解题思路:
十进制数变为其它进制的数应用循环除以R取余,然后倒序输出
*注意:考虑数的正负,正数时继续运行就行,而为负数时应先输出“-”。
*若为如12这样大于10进制的,10用’A’表示,11用‘B‘,可以根据ASCII码,将B 表示为 A +1。
题目代码:
#include<stdio.h>
#include<string.h>
int main()
{
int n,r,i;
while(scanf("%d %d",&n,&r)!=EOF)
{
if(n<0)
{
printf("-");n=-n;
}
if(n==0){printf("0\n");continue;}
int c=0,a[100];
while(n)
{
a[c]=(n%r);
c++;
n/=r;
}
for(i=c-1;i>=0;i--)
{
if(a[i]>=10)
{
printf("%c",'A'+a[i]-10);
}
else printf("%d",a[i]);
}
printf("\n");
}
}
- 十一、
题目:
A和B 都是由3个整数组成,分别表示时分秒,比如,假设A为34 45 56,就表示A所表示的时间是34小时 45分钟 56秒。
输入数据有多行组成,首先是一个整数N,表示测试实例的个数,然后是N行数据,每行有6个整数AH,AM,AS,BH,BM,BS,分别表示时间A和B所对应的时分秒。题目保证所有的数据合法。
解题思路:
题目代码:
#include<iostream>
using namespace std;
int ah,am,as,bh,bm,bs;
int main()
{
int n,i,ch,cm,cs;
while(cin>>n)
{
for(i=0;i<n;i++)
{
ah=0,am=0,as=0,bh=0,bm=0,bs=0;
cin>>ah>>am>>as>>bh>>bm>>bs;
cs=as+bs;
ch=ah+bh;
cm=am+bm;
cm=cm+cs/60;
ch=ch+cm/60;
cm=cm%60;
cs=cs%60;
cout<<ch<<" "<<cm<<" "<<cs<<endl;
}
}
}
- 十二、
题目:
A-B求的是两个集合的差,就是做集合的减法运算。(当然,大家都知道集合的定义,就是同一个集合中不会有两个相同的元素,这里还是提醒大家一下)
解题思路:
可以将A B两个集合的元素作为两个数组的元素,应用查找,如果B中有A中的元素可以将A中该元素变为0,后将A中元素不为0的输出。
*注意:此种方法要单独考虑A 中B中是否含有0元素。
*排序可以应用sort函数
//可以将程序优化,先排序后查找,排序后查找可以减少循环。
题目代码:
#include<iostream>
#include<algorithm>
using namespace std;
int a[105],b[105],c[105];
int main()
{
int m,n,i,y,t,o,j;
while(cin>>n>>m)
{
if(n==0&&m==0) break;
y=0;
for(i=0;i<n;i++)
{
cin>>a[i];
if(a[i]==0) y=1;
}
for(i=0;i<m;i++)
{
cin>>b[i];
if(y==1&&b[i]==0) y=2;
}
if(y==1) cout<<0<<" ";
t=0;
o=0;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(a[i]==b[j]) a[i]=0;
}
if(a[i]!=0)
{
c[o]=a[i];
o++;
t=1;
}
}
sort(c,c+o);
for(i=0;i<o;i++)
cout<<c[i]<<" ";
if(y!=1&&t==0) cout<<"NULL";
cout<<endl;
}
}
- 十三、
题目:
求A^B的最后三位数表示的整数。
说明:A^B的含义是“A的B次方”
解题思路:
应用for循环表示A^B。
*注意每输入一组都要将表示乘积的c=1。
题目代码:
#include<iostream>
using namespace std;
int main()
{
int a,b,i,c;
while(cin>>a>>b)
{
if(a==0&&b==0) break;
c=1;
for(i=0;i<b;i++)
c=(c*a)%1000;
cout<<c<<endl;
}
}
- 十四、
题目:
大家都知道,手机号是一个11位长的数字串,同时,作为学生,还可以申请加入校园网,如果加入成功,你将另外拥有一个短号。假设所有的短号都是是 6+手机号的后5位,比如号码为13512345678的手机,对应的短号就是645678。
现在,如果给你一个11位长的手机号码,你能找出对应的短号吗?
解题思路:
可以将该十一位数字串看做一个有十一位的数,后六位就可用a[i]除以100000取余表示,而前边加一个6可以将余数+600000或者先输出数字6。
*注意:当为极限值时会用int表示不了,用long long 定义数组。
题目代码:
#include<iostream>
using namespace std;
long long a[202];
int main()
{
int n,i;
while(cin>>n)
{
for(i=0;i<n;i++)
{
cin>>a[i];
cout<<600000+a[i]%100000<<endl;
}
}
}
- 十五、
题目:
有如下方程:Ai = (Ai-1 + Ai+1)/2 - Ci (i = 1, 2, 3, .... n).
若给出A0, An+1, 和 C1, C2, .....Cn.
请编程计算A1 = ?
解题思路:
该题可以数学知识先将其解出。
Ai=(Ai-1+Ai+1)/2 - Ci,
A1=(A0 +A2 )/2 - C1;
A2=(A1 + A3)/2 - C2 , ...
=> A1+A2 = (A0+A2+A1+A3)/2 - (C1+C2)
=> A1+A2 = A0+A3 - 2(C1+C2)
同理可得:
A1+A1 = A0+A2 - 2(C1)
A1+A2 = A0+A3 - 2(C1+C2)
A1+A3 = A0+A4 - 2(C1+C2+C3)
A1+A4 = A0+A5 - 2(C1+C2+C3+C4)
...
A1+An = A0+An+1 - 2(C1+C2+...+Cn)
----------------------------------------------------- 左右求和
(n+1)A1+(A2+A3+...+An) = nA0 +(A2+A3+...+An) + An+1 - 2(nC1+(n-1)C2+...+2Cn-1+Cn)
=> (n+1)A1 = nA0 + An+1 - 2(nC1+(n-1)C2+...+2Cn-1+Cn)
=> A1 = [nA0 + An+1 - 2(nC1+(n-1)C2+...+2Cn-1+Cn)]/(n+1)
再根据循环直接利用公式解出答案即可。
题目代码:
#include<iostream>
using namespace std;
double c[3002];
int main()
{
int n,i,sum;
double x,y,a;
while(cin>>n)
{
cin>>x>>y;
sum=0;
for(i=1;i<=n;i++)
{
cin>>c[i];
sum=sum+(n-i+1)*c[i];
}
a=(n*x+y-2*sum)/(n+1);
printf("%.2lf",a);
cout<<endl;
}
}