FIRST 十五道题
第一题
题目:
输入一个百分制的成绩t,将其转换成对应的等级,具体转换规则如下:
90~100为A;
80~89为B;
70~79为C;
60~69为D;
0~59为E;
输入:
输入数据有多组,每组占一行,由一个整数组成。
输出
对于每组输入数据,输出一行。如果输入数据不在0~100范围内,请输出一行:“Score is error!”。
题目分析:
输入一个0-100之间的数,判断它属于哪个分数段,并输出对应的字母。
解题思路:
用while循环输入一个数t,在循环体中判断这个数属于哪个分数段,并规定,如果这个数属于某个分数段,就输出指定的大写字母。
程序源代码:
#include<iostream>
using namespace std;
int main()
{
int t;
while(cin>>t)
{
if (t<=100&&t>=90)
cout<<"A"<<endl;
if (t>=80&&t<=89)
cout<<"B"<<endl;
if (t>=70&&t<=79)
cout<<"C"<<endl;
if (t>=60&&t<=69)
cout<<"D"<<endl;
if (t>=0&&t<=59)
cout<<"E"<<endl;
if (t<0||t>100)
cout<<"Score is error!"<<endl;
}
return 0;
}
细节:
1.循环输入一个数可以用while
while(cin>>t)
{
}
2.需要注意的是,样例输出的大写字母每个一列,所以输出的时候要添加endl。
第二题
题目:
春天是鲜花的季节,水仙花就是其中最迷人的代表,数学上有个水仙花数,他是这样定义的:
“水仙花数”是指一个三位数,它的各位数字的立方和等于其本身,比如:153=1^3+5^3+3^3。
现在要求输出所有在m和n范围内的水仙花数。
输入:
输入数据有多组,每组占一行,包括两个整数m和n(100<=m<=n<=999)。
输出:
对于每个测试实例,要求输出所有在给定范围内的水仙花数,就是说,输出的水仙花数必须大于等于m,并且小于等于n,如果有多个,则要求从小到大排列在一行内输出,之间用一个空格隔开;
如果给定的范围内不存在水仙花数,则输出no;
每个测试实例的输出占一行。
题目分析:
输入两个数,判断这两个数之间的每一个数的百位,十位,个位的三次方是否等于这个数,如果满足条件,输出这个数,如果不满足,输出no。
解题思路:
用while循环输入m,n两个整数,用for循环依次取出m到n之间的整数的百位,十位,个位。再用if条件判断是否满足条件,不满足输出no,满足的话,用for循环顺序输出。
程序源代码:
#include<iostream>
#include<cstdio>
using namespace std;
int p[1001];
int main()
{
int b=0,c=0,d=0,m,n,s=0;
while(cin>>m>>n)
{
s=0;
for(int a=m;a<=n;a++)
{
b=a/100;
c=a/10%10;
d=a%10;
if(a==b*b*b+c*c*c+d*d*d)p[++s]=a;
}
if(s==0)cout<<"no"<<endl;
else
for(int i=1;i<=s;i++)
{
if (i==s)cout<<p[i]<<endl;
else cout<<p[i]<<" ";
}
}
return 0;
}
细节:
1.怎么输出一个三位数的各个位上的数字:
百位=a/100;
十位=a/10%10;
个位=a%10;
2.输出满足的数的时候,要注意每个数之间有一个空格,特别的,最后一个数输出后,其后没有空格。
第三题
题目
作为杭电的老师,最盼望的日子就是每月的8号了,因为这一天是发工资的日子,养家糊口就靠它了,呵呵
但是对于学校财务处的工作人员来说,这一天则是很忙碌的一天,财务处的小胡老师最近就在考虑一个问题:如果每个老师的工资额都知道,最少需要准备多少张人民币,才能在给每位老师发工资的时候都不用老师找零呢?
这里假设老师的工资都是正整数,单位元,人民币一共有100元、50元、10元、5元、2元和1元六种。
输入
输入数据包含多个测试实例,每个测试实例的第一行是一个整数n(n<100),表示老师的人数,然后是n个老师的工资。
n=0表示输入的结束,不做处理。
输出
对于每个测试实例输出一个整数x,表示至少需要准备的人民币张数。每个输出占一行。
题目分析:有100.50.10.5.2.1六种钱,给定一个正整数,用这六种钱凑够这个整数,求钱的张数。
解题思路:
用while输入老师的人数n,用for循环输入每个老师的工资,再用for循环求每个老师的六种钱的张数的和,输出这个和。
程序源代码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n,i;
int a[101];
int a100,a50,a10,a5,a2,a1,t1,t2;
while(scanf("%d",&n),n!=0)
{
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
} //循环输入n个老师的钱数
int sum=0;
for(i=0;i<n;i++)
{
a100=a[i]/100; //求面值为100的张数
t1=a[i]%100;
a50=t1/50; //求面值为50的张数
t2=t1%50;
a10=t2/10; //求面值为10的张数
t1=t2%10;
a5=t1/5; //求面值为5的张数
t2=t1%5;
a2=t2/2; //求面值为2的张数
t1=t2%2;
a1=t1; //求面值为1的张数
sum=a100+a50+a10+a5+a2+a1+sum; //张数和
}
printf("%d\n",sum);
}
return 0;
}
细节:
1.stdlib 头文件即standard library标准库头文件。 stdlib 头文件里包含了C、C++语言的最常用的系统函数, stdlib.h里面定义了五种类型、一些宏和通用工具函数。
2.将每个老师的钱数定义为数组循环输入。
3.通过求余和除法运算求每种面值的钱的张数。
第四题
题目
妈妈每天都要出去买菜,但是回来后,兜里的钱也懒得数一数,到底花了多少钱真是一笔糊涂帐。现在好了,作为好儿子(女儿)的你可以给她用程序算一下了,呵呵。
输入
输入含有一些数据组,每组数据包括菜种(字串),数量(计量单位不论,一律为double型数)和单价(double型数,表示人民币元数),因此,每组数据的菜价就是数量乘上单价。菜种、数量和单价之间都有空格隔开的。
输出
支付菜价的时候,由于最小支付单位是角,所以总是在支付的时候采用四舍五入的方法把分头去掉。最后,请输出一个精度为角的菜价总量。
题目分析:
输入含有一些数据组,每组数据包括菜种,数量和单价,求花的总钱数。
解题思路:
用while循环输入菜种,单价和数量,应用单价乘数量等于总价的公式,求出花的每个菜种的钱数,再对这些钱数求和。
程序源代码:
#include<stdio.h>
int main()
{
double s,d,sum;
char str[100];
sum=0;
while(scanf("%s%lf%lf",str,&s,&d)!=EOF)
{
sum+=s*d;
}
printf("%.1lf\n",sum);
return 0;
}
细节:
1.在输入单价和数量时用到了scanf("%s%lf%lf",str,&s,&d)!=EOF 即输入的数据不为负数。
2.菜种要定义为char类型,单价和数量定义为double类型。
第五题
题目
青年歌手大奖赛中,评委会给参赛选手打分。选手得分规则为去掉一个最高分和一个最低分,然后计算平均得分,请编程输出某选手的得分。
输入
输入数据有多组,每组占一行,每行的第一个数是n(2<n<=100),表示评委的人数,然后是n个评委的打分。
输出
对于每组输入数据,输出选手的得分,结果保留2位小数,每组输出占一行。
题目分析:
输入n个数,去掉一个最大和最小的数,求剩余数的平均值。
解题思路:
用while输入数n,for循环输入n个数,并求出这n个数的和,再用if条件找到最大和最小值,用总和减去最大和最小值,再求出平均值。
程序源代码:
#include<stdio.h>
int main()
{
int n,i,sum=0,min,max,grade;
double aver;
while(scanf("%d",&n)!=EOF)
{
min=100;
max=0;
sum=0;
for(i=0;i<n;i++)
{
scanf("%d",&grade);
sum+=grade;
if(min>grade)
{
min = grade;
}
if(max<grade)
{
max = grade;
}
}
aver = (sum-max-min)*1.00/(n-2);
printf("%.2lf\n",aver);
}
return 0;
}
细节:
1.在输入n时用到了scanf("%s%lf%lf",str,&s,&d)!=EOF 即输入的数据不为负数。
2.在求去掉最大值和最小值的剩余数时,可用先求出所有数的和,再减去最大值和最小值的方法求得。也可用排序的方法求出。
第六题
题目:
输入n(n<=100)个整数,按照绝对值从大到小排序后输出。题目保证对于每一个测试实例,所有的数的绝对值都不相等。
输入
输入数据有多组,每组占一行,每行的第一个数字为n,接着是n个整数,n=0表示输入数据的结束,不做处理。
输出
对于每个测试实例,输出排序后的结果,两个数之间用一个空格隔开。每个测试实例占一行。
题目分析:
输入n个整数,按绝对值大小排序后输出。
解题思路:
用while输入n,for 循环输入n个数,比较数的平方的大小排序后输出。
程序源代码:
#include<iostream>
using namespace std;
int main()
{
int n,p,i,j,a[101];
while(cin>>n&&n!=0)
{
for(i=0;i<n;i++)
cin>>a[i];
for(j=0;j<n;j++)
for(i=0;i<n-1-j;i++)
if(a[i]*a[i]<a[i+1]*a[i+1])
{
p=a[i];
a[i]=a[i+1];
a[i+1]=p;
}
for(i=0;i<n-1;i++)
cout<<a[i]<<" ";
cout<<a[n-1]<<endl;
}
}
细节:
1.用(cin>>n&&n!=0)表示输入数据n=0时结束。
2.比较两个数的大小可用求两个数的平方比较。
3.输出时要注意每个数之间有一个空格,特别的,最后一个数输出后,其后没有空格。所以可以写成for(i=0;i<n-1;i++)
cout<<a[i]<<" ";
cout<<a[n-1]<<endl;
第七题
题目
对于表达式n^2+n+41,当n在(x,y)范围内取整数值时(包括x,y)(-39<=x<y<=50),判定该表达式的值是否都为素数。
输入
输入数据有多组,每组占一行,由两个整数x,y组成,当x=0,y=0时,表示输入结束,该行不做处理。
输出
对于每个给定范围内的取值,如果表达式的值都为素数,则输出"OK",否则请输出“Sorry”,每组输出占一行。
题目分析:
给定某个范围,对于范围中的每个数代入表达式n^2+n+41的值,判断求出的数是否为素数,若都是素数,输出“OK”,否则,输出“Sorry”。
解题思路:
用while输入m,n,判断m,n是否为0,如果不是,将m,n之间的数代入表达式中求出函数值,再判断是不是素数,最后按条件输出。
程序源代码:
#include <stdio.h>
int a[11000];
int main(){
int p,q,e,i,m,n,j;
while(scanf("%d%d",&m,&n)!=-1)
{
q=0;
if(m==0&&n==0) return 0;
else{
j=0;
for(i=m;i<=n;i++)
{
j++;
a[j]=i*i+i+41;
}
for(i=1;i<=j;i++)
{for(p=2;p*p<=a[i];p++)
{ if(a[i]%p==0) q++;}}
if(q==0) printf("OK\n");
if(q!=0) printf("Sorry\n");
}
}
return 0;
}
细节:
1.要让求出的函数值用数组储存,可以写成
j=0;
for(i=m;i<=n;i++)
{
j++;
a[j]=i*i+i+41;
}
2.判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数。
第八题
题目
有n(n<=100)个整数,已经按照从小到大顺序排列好,现在另外给一个整数x,请将该数插入到序列中,并使新的序列仍然有序。
输入
输入数据包含多个测试实例,每组数据由两行组成,第一行是n和m,第二行是已经有序的n个数的数列。n和m同时为0标示输入数据的结束,本行不做处理。
输出
对于每个测试实例,输出插入新的元素后的数列。
题目分析:
已有从小到大排好顺序的n个整数,现另给一个数x将其插入期中,使新的序列仍然有序。
解题思路:
用while输入n,m.n表示有n个数,m表示要插入的数,用for循环输入n个有序的数,判断m与a[i]的大小,从而确定要插入的位置,最后顺序输出n+1个数。
程序源代码:
#include<iostream>
#include<cstdio>
#include<iomanip>
using namespace std;
int main()
{
int n,a[110],m,s,i,j;
while(cin>>n>>m,n!=0&&m!=0)
{
for(i=1;i<=n;i++)
cin>>a[i];
for(i=1;i<=n;i++)
{
if(m<a[i])
break;
}
for(j=1;j<i;j++)
cout<<a[j]<<" ";
cout<<m;
for(j=i;j<=n;j++)
cout<<" "<<a[j];
cout<<endl;
}
}
细节:
1.用(cin>>n>>m,n!=0&&m!=0)表示当m和n等于0时结束。
2.插入一个数,并顺次输出的方法为for(i=1;i<=n;i++)
{
if(m<a[i])
break;
}
for(j=1;j<i;j++)
cout<<a[j]<<" ";
cout<<m;
for(j=i;j<=n;j++)
cout<<" "<<a[j];
cout<<endl;
3.插入数后,输出时要注意空格,最后一个数后不能有空格。
第九题
题目
有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行。请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数。
输入
输入数据的第一行是一个整数N,表示测试实例的个数,然后是N 行数据,每行包含两个整数a和b(0<a<b<50)。
输出
对于每个测试实例,请输出蜜蜂从蜂房a爬到蜂房b的可能路线数,每个实例的输出占一行。
题目分析:
a到b的路线图有几种。
解题思路:
想知道从a到b可能的路线数就需要知道到达b-1的路线数和b-2的路线数,即f(b)=f(b-1)+f(b-2),即斐波拉契数列递推式(还需要注意的斐波拉契数列的递推式求出的结果可能会溢出)
程序源代码:
#include<iostream>
using namespace std;
int main()
{
int i,m,j,q;
long long a,b,p;
cin>>m;
for(i=0; i<m; i++)
{
a=1,b=0;
cin>>j>>q;
for(int t=0; t<=q-j; t++)
{
p=b;
b=a+b;
a=p;
}
cout<<b<<endl;
}
return 0;
}
细节:
1.找规律,递推出公式,即斐波拉契数列。
2.定义a,b为long long int 型。
第十题
题目
“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。请写一个程序判断读入的字符串是否是“回文”。
输入
输入包含多个测试实例,输入数据的第一行是一个正整数n,表示测试实例的个数,后面紧跟着是n个字符串。
输出
如果一个字符串是回文串,则输出"yes",否则输出"no".
题目分析:
输入n,再输入n个字符串,判断正读反读是否一样,如果是,输出“yes”,否则输出“no”。
解题思路:
用while输入p,再输入p个字符串,求出字符串的长度,从字符串的第一个字符向后,最后一个字符向前,比较是否相同,再按题目要求输出。
程序源代码:
#include<stdio.h>
#include<string.h>
int main()
{
char str[100010];
int p,l,i,j;
while(~scanf("%d",&p))
{
getchar();
while(p--)
{
gets(str);
l=strlen(str);
for(i=0,j=l-1;i<j;i++,j--)
if(str[i]!=str[j])
{
printf("no\n");
break;
}
if(i>=j)
printf("yes\n");
}
}
}
细节:
1.求字符串的长度可用strlen(str)。
2.输入字符串用gets(str),其头文件为<string.h>。
3.判断字符串为回文串for循环中for(i=0,j=l-1;i<j;i++,j--)
第十一题
题目
给你n个整数,求他们中所有奇数的乘积。
输入
输入数据包含多个测试实例,每个测试实例占一行,每行的第一个数为n,表示本组数据一共有n个,接着是n个整数,你可以假设每组数据必定至少存在一个奇数。
输出
输出每组数中的所有奇数的乘积,对于测试实例,输出一行。
题目分析:
求n个整数中奇数的乘积。
解题思路:
用while输入n,用for循环输入n个整数,判断每个整数是否为奇数,若为奇数,则相乘,最后输出乘积。
程序源代码:
#include<iostream>
using namespace std;
int a[1000001];
int main()
{
int n,i,J;
while(cin>>n)
{
for(i=0;i<n;i++)
cin>>a[i];
J=1;
for(i=0;i<n;i++)
{
if(a[i]%2!=0)
J=J*a[i];
}
cout<<J<<endl;
}
}
细节:
奇数的判断:让一个数除2,若不能除尽,则这个数为奇数,否则,为偶数。奇数满足的条件: a[i]%2!=0。
第十二题
题目
大家都知道,手机号是一个11位长的数字串,同时,作为学生,还可以申请加入校园网,如果加入成功,你将另外拥有一个短号。假设所有的短号都是是 6+手机号的后5位,比如号码为13512345678的手机,对应的短号就是645678。
现在,如果给你一个11位长的手机号码,你能找出对应的短号吗?
输入
输入数据的第一行是一个N(N <= 200),表示有N个数据,接下来的N行每一行为一个11位的手机号码。
输出
输出应包括N行,每行包括一个对应的短号,输出应与输入的顺序一致。
题目分析:
输入一个11位的数字,取其后五位,输出6加上后五位这六个数字。
解题思路:
输入N,用while循环输入N个11位的数,分别输入每个数的11位,取其后五位,输出6后,顺次输出后五位。
程序源代码:
#include <iostream>
using namespace std;
int main()
{
int N;
char a[12];
cin >> N;
while (N--)
{
for (int i = 1; i <= 11; i++)
cin >> a[i];
cout << 6;
for (int i = 7; i <= 11; i++)
cout << a[i];
cout << endl;
}
return 0;
}
细节:
1.输入N后,输入N个数,可用while (N--)。
2.输出11位数的后五位可用
for (int i = 7; i <= 11; i++)
cout << a[i];
3.将11位的数字串定义为char类型。
第十三题
题目
多项式的描述如下:
1 - 1/2 + 1/3 - 1/4 + 1/5 - 1/6 + ...
现在请你求出该多项式的前n项的和。
输入
输入数据由2行组成,首先是一个正整数m(m<100),表示测试实例的个数,第二行包含m个正整数,对于每一个整数(不妨设为n,n<1000),求该多项式的前n项的和。
输出
对于每个测试实例n,要求输出多项式前n项的和。每个测试实例的输出占一行,结果保留2位小数。
解题思路:
用while输入m,for输入m个整数,从1到这个整数依次判断为奇数还是偶数,奇数的话相加,偶数相减。
程序源代码:
#include<stdio.h>
#include<math.h>
int main()
{
int m,n,i,j;
double sum;
while(scanf("%d",&m)!=EOF)
{
int a[9999];
sum=0;
for(i=0;i<m;i++)
scanf("%d",&a[i]);
for(i=0;i<m;i++)
{
for(j=0;j<a[i];j++)
{
if(j%2==0)
sum=sum+1.00/(j+1);
if(j%2==1)
sum=sum-1.00/(j+1);
}
printf("%.2f\n",sum);
sum=0;
}
}
return 0;
}
细节:
1.m输入为零时结束程序,可以用(scanf("%d",&m)!=EOF)。
2.结果保留两位小数可以进行以下操作
sum=sum-1.00/(j+1)
printf("%.2f\n",sum)
第十四题
题目
古希腊数学家毕达哥拉斯在自然数研究中发现,220的所有真约数(即不是自身的约数)之和为:
1+2+4+5+10+11+20+22+44+55+110=284。
而284的所有真约数为1、2、4、71、 142,加起来恰好为220。人们对这样的数感到很惊奇,并称之为亲和数。一般地讲,如果两个数中任何一个数都是另一个数的真约数之和,则这两个数就是亲和数。 你的任务就编写一个程序,判断给定的两个数是否是亲和数
输入
输入数据第一行包含一个数M,接下有M行,每行一个实例,包含两个整数A,B; 其中 0 <= A,B <= 600000 ;
输出
对于每个测试实例,如果A和B是亲和数的话输出YES,否则输出NO。
题目分析:
给定两个数A,B,若A的所有真约数之和等于B,并且B的真约数之和等于A,则输出“YES”,否则输出“NO”。
解题思路:
输入n,循环输入n组数,用for循环分别求A,B的真约数之和,判断是否等于B,A,并按题目输出指定字符。
程序源代码:
#include<iostream>
using namespace std;
int main()
{
int n,A,B,sum1,sum2,i,j;
cin>>n;
while(n--)
{
cin>>A>>B;
sum1=0;
for(i=1;i<A;i++)
{
if(A%i==0)
sum1+=i;
}
sum2=0;
for(j=1;j<B;j++)
{
if(B%j==0)
sum2+=j;
}
if(sum1==B&&sum2==A)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}
细节:
求一个数的真约数之和可以进行如下操作:
for(i=1;i<A;i++)
{
if(A%i==0)
sum1+=i;
}
第十五题
题目
喜欢西游记的同学肯定都知道悟空偷吃蟠桃的故事,你们一定都觉得这猴子太闹腾了,其实你们是有所不知:悟空是在研究一个数学问题!什么问题?他研究的问题是蟠桃一共有多少个!不过,到最后,他还是没能解决这个难题,当时的情况是这样的:第一天悟空吃掉桃子总数一半多一个,第二天又将剩下的桃子吃掉一半多一个,以后每天吃掉前一天剩下的一半多一个,到第n天准备吃的时候只剩下一个桃子。聪明的你,请帮悟空算一下,他第一天开始吃的时候桃子一共有多少个呢?
输入
输入数据有多组,每组占一行,包含一个正整数n(1<n<30),表示只剩下一个桃子的时候是在第n天发生的。
输出
对于每组输入数据,输出第一天开始吃的时候桃子的总数,每个测试实例占一行。
题目分析:
猴子吃桃,第一天吃掉总数的一半,之后的每一天都吃掉一半多一个,第n天吃的时候只有一个,求第一天吃的时候有多少个。
解题思路:
逆向考虑,从最后的第n天只剩一个开始,往前求,每次都是加一乘二计算出前一天的数量
程序源代码:
#include<iostream>
using namespace std;
int a[101];
int main()
{
int n,i;
while(cin>>n)
{
for(i=1;i+1<=n;i++)
{
a[1]=1;
a[i+1]=(a[i]+1)*2;
if(i+1==n)
cout<<a[i+1]<<endl;
}
}
}
SECOND 感想
上机实验是学习程序设计语言必不可少的实习环节,特别是c语言灵活、简洁,更需要通过编程的实习来真正掌握它。通过上机练习,我基本掌握了解题的思路,和一些问题的解决方法。当拿过一道题,我的第一感觉不是害怕它,而是想解决它,我认为这是我的一大进步。我觉得很多题目都离不开for和while循环,通过练习,我对它们更加熟悉了,相信以后运用的更加熟练。希望以后的学习中能运用C++和C解决实际问题,提高自己!