PTA刷题集合
第一章–无
输入样例:
输出样例:
第二章
实验2-3-8 计算火车运行时间
本题要求根据火车的出发时间和达到时间,编写程序计算整个旅途所用的时间。
输入格式:
输入在一行中给出2个4位正整数,其间以空格分隔,分别表示火车的出发时间和到达时间。每个时间的格式为2位小时数(00-23)和2位分钟数(00-59),假设出发和到达在同一天内。
输出格式:
在一行输出该旅途所用的时间,格式为“hh:mm”,其中hh为2位小时数、mm为2位分钟数。
输入样例:
1201 1530
输出样例:
03:29
思路:由于是24小时计时法,所以情况讨论就简单了许多。首先,因为题目中对输入数据限制为最多24h,所以可以将输入的数据类型分为两种。
第一种:出发时间是第一天,到达时间也是第一天,那计算时间==到达时间-出发时间。
第二种:出发时间是第一天,到达时间是第二天(出发时间<到达时间),可以这样考虑。首先将第一天出发时间到第一天结束时间(24:00)的时间间隔算出来(即:24:00-出发时间)。然后将24:00到第二天的到达时间算出来(即到达时间-0:00)。再将两者相加即为运行时间。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int h; //小时
int m; //分钟
int num1; //出发时间
int num2; //到达时间
scanf("%d%d",&num1,&num2);
h=num2/100-num1/100; //4位整型取前2位(小时)
m=num2%100-num1%100; //4位整型取余后2位(分钟)
if(m<0) //num1,num2都是在同一天,h一定大于0
{
m=60+m; //当m小于0,从h借来一小时,填补m的值
h=h-1;
}
printf("%02d:%02d\n",h,m);
return 0;
}
习题2-4 求交错序列前N项和
本题要求编写程序,计算交错序列 1-2/3+3/5-4/7+5/9-6/11+… 的前N项之和。
输入格式:
输入在一行中给出一个正整数N。
输出格式:
在一行中输出部分和的值,结果保留三位小数。
输入样例:
5
输出样例:
0.917
思路:乍一看,这个算式非常的麻烦。但是在编写程序的时候应当一步一步的解决算式。首先,先将这个题目算式看做不同的数据相加而形成的(先处理多项式中的单项),通过观察可以发现,单项之间的不同在于符号(正负号),分子,分母的不同,但是这些都是有规律的。根据规律写出来即可。
#include<stdio.h>
int main(void)
{
int i, flag, b, d, n;
double sum;
scanf("%d", &n);
sum=0;
flag=1;
d=1;
b=1;
for(i=1; i<=n; i++){
sum=sum+b*flag*1.0/d;
flag=flag+1;
b=-b;
d=d+2;
}
printf("%.3f", sum);
return 0;
}
第三章
习题3-1 比较大小
本题要求将输入的任意3个整数从小到大输出。
输入格式:
输入在一行中给出3个整数,其间以空格分隔。
输出格式:
在一行中将3个整数从小到大输出,其间以“->”相连。
输入样例:
4 2 8
输出样例:
2->4->8
思路:这里涉及到了若想要两个变量的值交换,则需要第三个变量。举一个形象的例子,如果将变量a,b看做两个不同的杯子,a里面装的是可乐,b里面装的是雪碧,想要让两个杯子中的饮料交换,需要第三个杯子帮助。
#include<stdio.h>
int main(){
int a,b,c;
int temp;
scanf("%d %d %d",&a,&b,&c);
if(a>b){
a=a;
}else{
temp=a;
a=b;
b=temp;
}
if(a>c){
a=a;
}else{
temp=a;
a=c;
c=temp;
}
if(b>c){
b=b;
}else{
temp=b;
b=c;
c=temp;
}
printf("%d->%d->%d",c,b,a);
return 0;
}
实验3-4 统计字符[2]
本题要求编写程序,输入N个字符,统计其中英文字母、空格或回车、数字字符和其他字符的个数。
输入格式:
输入在第一行中给出正整数N,第二行输入N个字符,最后一个回车表示输入结束,不算在内。
输出格式:
在一行内按照
letter = 英文字母个数, blank = 空格或回车个数, digit = 数字字符个数, other = 其他字符个数
的格式输出。请注意,等号的左右各有一个空格,逗号后有一个空格。
输入样例:
10
aZ &
09 Az
输出样例:
letter = 4, blank = 3, digit = 2, other = 1
思路:没什么好说的,这里涉及到ASCII编码,和char变量的相关知识。
#include <stdio.h>
int main()
{
char ch;
int times;
scanf("%d%c",×,&ch);
int a,b,c,d;
a=0;
b=0;
c=0;
d=0;
while(times!=0)
{
ch=getchar();
//
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{a++;}
else if(ch==' '||ch=='\n')
{b++;}
else if(ch>='0'&&ch<='9')
{c++;}
else
{d++;}
times--;
}
printf("letter = %d, blank = %d, digit = %d, other = %d\n",a,b,c,d);
return 0;
}
实验3-11 求一元二次方程的根
本题目要求一元二次方程a**x2+b**x+c=0的根,结果保留2位小数。
输入格式:
输入在一行中给出3个浮点系数a、b、c,中间用空格分开。
输出格式:
根据系数情况,输出不同结果:
1)如果方程有两个不相等的实数根,则每行输出一个根,先大后小;
2)如果方程有两个不相等复数根,则每行按照格式“实部+虚部i”输出一个根,先输出虚部为正的,后输出虚部为负的;
3)如果方程只有一个根,则直接输出此根;
4)如果系数都为0,则输出"Zero Equation";
5)如果a和b为0,c不为0,则输出"Not An Equation"。
输入样例1:
2.1 8.9 3.5
输出样例1:
-0.44
-3.80
输入样例2:
1 2 3
输出样例2:
-1.00+1.41i
-1.00-1.41i
输入样例3:
0 2 4
输出样例3:
-2.00
输入样例4:
0 0 0
输出样例4:
Zero Equation
输入样例5:
0 0 1
输出样例5:
Not An Equation
思路:
#include <stdio.h>
#include <math.h>
int main()
{
double a,b,c;
scanf("%lf %lf %lf",&a,&b,&c);
double delt;
delt=pow(b,2)-(4*a*c);
if(a==0&&b==0&&c==0)
{
printf("Zero Equation\n");
}else if(a==0&&b==0&&c!=0)
{
printf("Not An Equation\n");
}else if(a==0)
{
printf("%.2lf\n",(-c)/b);
}else
{
if(delt==0)
{
double r=(-b)/(2*a);
printf("%.2lf\n",r);
}else if(delt>0)
{
double r1=(-b+sqrt(delt))/(2*a);
double r2=(-b-sqrt(delt))/(2*a);
printf("%.2lf\n",r1);
printf("%.2lf\n",r2);
}else
{
if(b==0) b=(-b); //解决纯虚根情况
double r3=(-b)/(2*a);
double r4=(sqrt(-delt)/(2*a));
printf("%.2lf+%.2lfi\n",r3,r4);
printf("%.2lf-%.2lfi\n",r3,r4);
}
}
return 0;
}
第四章
习题4-9 打印菱形图案
本题要求编写程序,打印一个高度为n的、由“*”组成的正菱形图案。
输入格式:
输入在一行中给出一个正的奇数n。
输出格式:
输出由n行星号“*”组成的菱形,如样例所示。每个星号后跟一个空格。
输入样例:
7
输出样例:
*
* * *
* * * * *
* * * * * * *
* * * * *
* * *
*
思路1:
#include <stdio.h>
int main()
{
int height;
scanf("%d",&height);
int h=(height+1)/2;
for(int i=1;i<height;i=i+2)
{
for(int x=1;x<h;x++)
{ printf(" "); }
h--;
for(int y=1;y<=i;y++)
{
printf("* ");
}
printf("\n");
}
for(int z=1;z<=height;z++)
{
printf("* ");
}
printf("\n");
h=1;
for(int i=height-2;i>0;i=i-2)
{
for(int x=1;x<=h;x++)
{ printf(" "); }
h++;
for(int y=1;y<=i;y++)
{
printf("* ");
}
printf("\n");
}
return 0;
}
思路2:
#include <cstdio>
#include <cmath>
int main()
{
int hang;
scanf("%d",&hang);
int centerx =hang/2;
int centery =hang/2;
for(int i=0;i<hang;i++)
{
for(int j=0;j<hang;j++)
{
if(abs(i-centerx)+abs(j-centery) <= hang/2)
printf("*");
else
printf(" ");
}
printf("\n");
}
return 0;
}
习题4-11 兔子繁衍问题
一对兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。假如兔子都不死,请问第1个月出生的一对兔子,至少需要繁衍到第几个月时兔子总数才可以达到N对?
输入格式:
输入在一行中给出一个不超过10000的正整数N。
输出格式:
在一行中输出兔子总数达到N最少需要的月数。
输入样例:
30
输出样例:
9
思路:
#include<stdio.h>
int main(){
double sum;
int n1,n2,n3;
scanf("%lf",&sum);
int i;
if (sum==0||sum==1){
printf("1");
return 0;
} else if(sum==2){
printf("3");
return 0;
}
n1=1;
n2=1;
for(i=3;;i++){
n3=n1+n2;
if(n3>=sum){
break;
}
n1=n2;
n2=n3;
}
printf("%d",i);
}
习题4-6 水仙花数
水仙花数是指一个N位正整数(N≥3),它的每个位上的数字的N次幂之和等于它本身。例如:153=13+53+33。 本题要求编写程序,计算所有N位水仙花数。
输入格式:
输入在一行中给出一个正整数N(3≤N≤7)。
输出格式:
按递增顺序输出所有N位水仙花数,每个数字占一行。
输入样例:
3
输出样例:
153
370
371
407
思路:
#include <stdio.h>
int p(int a,int b);
int main()
{
int n;
int sum=0;
int num=0;
int number;
scanf("%d",&n);
int begin=p(10,(n-1));
int fin=p(10,n)-1;
for(int i=begin;i<=fin;i++)
{
number=i;
for(int x=1;x<=n;x++)
{
num=number%10;
sum+=p(num,n);
//printf("?????sum=%d\n",sum);
number=number/10;
//printf("num=%d number=%d\n",num,number);
}
//printf("!!!sum=%d i=%d\n",sum,i);
if(sum==i)
{
printf("%d\n",sum);
}
sum=0;//问题在这里!
}
return 0;
}
int p(int a,int b){ //求幂函数的定义
int pow=1,j;
for(j=1;j<=b;j++)
{
pow=pow*a;
}
return pow;
}
习题4-5 换硬币
将一笔零钱换成5分、2分和1分的硬币,要求每种硬币至少有一枚,有几种不同的换法?
输入格式:
输入在一行中给出待换的零钱数额x∈(8,100)。
输出格式:
要求按5分、2分和1分硬币的数量依次从大到小的顺序,输出各种换法。每行输出一种换法,格式为:“fen5:5分硬币数量, fen2:2分硬币数量, fen1:1分硬币数量, total:硬币总数量”。最后一行输出“count = 换法个数”。
输入样例:
13
输出样例:
fen5:2, fen2:1, fen1:1, total:4
fen5:1, fen2:3, fen1:2, total:6
fen5:1, fen2:2, fen1:4, total:7
fen5:1, fen2:1, fen1:6, total:8
count = 4
思路:
#include<stdio.h>
int main()
{
int x;
int count=0;
scanf("%d",&x);
if(x>8&&x<100)
{
int i;
for(i=x/5;i>=1;i--)
{
int j;
for(j=x/2;j>=1;j--)
{
int k;
for(k=x;k>=1;k--)
{
if(x==i*5+j*2+k)
{
printf("fen5:%d, fen2:%d, fen1:%d, total:%d\n",i,j,k,i+j+k);
count=count+1;
}
}
}
}
printf("count = %d\n",count);
}
return 0;
}
习题4-2 求幂级数展开的部分和
已知函数e**x可以展开为幂级数1+x+x2/2!+x3/3!+⋯+x**k/k!+⋯。现给定一个实数x,要求利用此幂级数部分和求e**x的近似值,求和一直继续到最后一项的绝对值小于0.00001。
输入格式:
输入在一行中给出一个实数x∈[0,5]。
输出格式:
在一行中输出满足条件的幂级数部分和,保留小数点后四位。
输入样例:
1.2
输出样例:
3.3201
思路:
#include<stdio.h>
#include<math.h>
double fun(double x,double n)//求数列每一项的值
{
double ret = 0;
double i = 0;
double num = 1;
//求分母:即阶乘
for (i = 1; i <=n; i++)
{
num = num*i;
}
ret = pow(x, n) / num;//数列每一项的值
//printf("ret=%.4f,", ret);
return ret;
}
int main()
{
double x = 0;
double sum = 0;
double n = 0;
scanf("%lf", &x);
do
{
sum = sum + fun(x, n);
//printf("n=%lf,sum=%.4f\n",n, sum);//加入这些输出语句都是便于查看各项值,方便调试所用
n++;
} while (fabs(fun(x, n)) >= 0.00001);
sum = sum + fun(x, n);//最后一项的绝对值必须小于0.00001,而上面的循环sum的值没有把最后一项包含进去,所以此处要添加这一句
//printf("n=%lf\n", n);
printf("%.4f\n", sum);
return 0;
}
习题4-7 最大公约数和最小公倍数
本题要求两个给定正整数的最大公约数和最小公倍数。
输入格式:
输入在一行中给出两个正整数M和N(≤1000)。
输出格式:
在一行中顺序输出M和N的最大公约数和最小公倍数,两数字间以1空格分隔。
输入样例:
511 292
输出样例:
73 2044
思路:
//最大公约数=两数之积/最小公倍数,所以只要求出一个另
//外一个自然通过简单的计算求出来了。
//辗转相除法
//有两整数a和b:
// a%b得余数c
// 若c=0,则b即为两数的最大公约数
// 若c≠0,则a=b,b=c,再回去执行
//例如求35和15的最大公约数过程为:
//35÷15 余5,,15÷5余0,5即为最大公约数
#include <stdio.h>
#include <math.h>
int main(){ //浮点错误是所求值不存在 除以0之类了
int m,n;
scanf("%d %d",&m,&n);
int yushu;
yushu=m%n;
int x;
x=m*n;//记录m*n为后面求公倍数
if(yushu==0){
printf("%d %d",n,x/n);
}else{
while(yushu!=0){
m=n;
n=yushu;
yushu=m%n;
}
printf("%d %d",n,x/n);
}
return 0;
}
实验4-1-1 统计数字字符和空格
本题要求编写程序,输入一行字符,统计其中数字字符、空格和其他字符的个数。建议使用switch语句编写。
输入格式:
输入在一行中给出若干字符,最后一个回车表示输入结束,不算在内。
输出格式:
在一行内按照
blank = 空格个数, digit = 数字字符个数, other = 其他字符个数
的格式输出。请注意,等号的左右各有一个空格,逗号后有一个空格。
输入样例:
在这里给出一组输入。例如:
Reold 12 or 45T
输出样例:
在这里给出相应的输出。例如:
blank = 3, digit = 4, other = 8
思路:
#include <stdio.h>
int main()
{
char c;
int blank=0,digit=0,other=0;
while(scanf("%c",&c)&&c!='\n'){
switch(c)
{
case ' ': blank++;break;
case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': digit++;break;
default : other++;
}
}
printf("blank = %d, digit = %d, other = %d",blank,digit,other);
return 0;
}
实验4-2-8 验证“哥德巴赫猜想”**
数学领域著名的“哥德巴赫猜想”的大致意思是:任何一个大于2的偶数总能表示为两个素数之和。比如:24=5+19,其中5和19都是素数。本实验的任务是设计一个程序,验证20亿以内的偶数都可以分解成两个素数之和。
输入格式:
输入在一行中给出一个(2, 2 000 000 000]范围内的偶数N。
输出格式:
在一行中按照格式“N = p + q”输出N的素数分解,其中p ≤ q均为素数。又因为这样的分解不唯一(例如24还可以分解为7+17),要求必须输出所有解中p最小的解。
输入样例:
24
输出样例:
24 = 5 + 19
#include <stdio.h>
#include <math.h>
int sushu(int n)
{
int i,iprsem=1;
if(n==2)
iprsem=1;
else if(n==1)
iprsem=0;
else{
for(i=2;i<=sqrt(n);i++){
if(n%i==0){
iprsem=0;
break;
}
}
}
if(iprsem==0)
return 0;
else
return 1;
}
int main()
{
int N;
scanf("%d",&N);
int i,j;
for(i=2;i<=N;i++){
int t=N-i;
if(sushu(i)&&sushu(t)){
printf("%d = %d + %d",N,i,t);
break;
}
}
return 0;
}
第五章
练习6-3 英文字母替换加密(大小写转换+后移1位)
本题要求编写程序,将英文字母替换加密。为了防止信息被别人轻易窃取,需要把电码明文通过加密方式变换成为密文。变换规则是:将明文中的所有英文字母替换为字母表中的后一个字母,同时将小写字母转换为大写字母,大写字母转换为小写字母。例如,字母a->B、b->C、…、z->A、A->b、B->c、…、Z->a。输入一行字符,将其中的英文字母按照以上规则转换后输出,其他字符按原样输出。
输入格式:
输入一行字符,以回车符 '\n’作为 结束符。
输出格式:
将输入的一行字符中的所有英文字母替换为字母表中的后一个字母,同时将小写字母转换为大写字母,大写字母转换为小写字母后输出,其他字符按原样输出。
输入样例:
在这里给出一组输入。例如:
Reold Z123?
输出样例:
在这里给出相应的输出。例如:
sFPME a123?
思路:
#include <stdio.h>
int main()
{
char ch;
ch=getchar();
while(ch!='\n')
{
if(ch>='a'&&ch<'z')
{
ch=ch-32;
ch=ch+1;
}else if(ch>='A'&&ch<'Z')
{
ch=ch+32;
ch=ch+1;
}else if(ch=='z')
{
ch='A';
}else if(ch=='Z')
{
ch='a';
}
putchar(ch);
ch=getchar();
}
return 0;
}
习题6-7 简单计算器
模拟简单运算器的工作。假设计算器只能进行加减乘除运算,运算数和结果都是整数,四种运算符的优先级相同,按从左到右的顺序计算。
输入格式:
输入在一行中给出一个四则运算算式,没有空格,且至少有一个操作数。遇等号”=”说明输入结束。
输出格式:
在一行中输出算式的运算结果,或者如果除法分母为0或有非法运算符,则输出错误信息“ERROR”。
输入样例:
1+2*10-10/2=
输出样例:
10
思路:
#include <stdio.h>
int main()
{
char ch;
int num1,num2;
scanf("%d",&num1);
int flag=1;
while(ch!='=')
{
scanf("%c",&ch);
scanf("%d",&num2);
if(ch=='=')
{
break;
}
if(ch=='+')
{
num1=num1+num2;
}else if(ch=='-')
{
num1=num1-num2;
}else if(ch=='*')
{
num1=num1*num2;
}else if(ch=='/')
{
if(num2==0)
{
printf("ERROR\n");
flag=0;
}else
{
num1=num1/num2;
}
}else{
printf("ERROR\n");
flag=0;
}
}
if(flag==1)
{
printf("%d\n",num1);
}
return 0;
}
习题6-8 单词首字母大写
本题目要求编写程序,输入一行字符,将每个单词的首字母改为大写后输出。所谓“单词”是指连续不含空格的字符串,各单词之间用空格分隔,空格数可以是多个。
输入格式:
输入给出一行字符。
输出格式:
在一行中输出已输入的字符,其中所有单词的首字母已改为大写。
输入样例:
How are you?
输出样例:
How Are You?
思路:
#include <stdio.h>
int main(){
int flag=1;
char ch;
while((ch=getchar())!='\n'){
if(ch==' '){
flag=1;
}else if(flag==1){
flag=0;
if(ch>='a'&&ch<='z'){
ch=ch-'a'+'A';
}
}
putchar(ch);
}
return 0;
}
实验6-9 使用函数输出指定范围内的Fibonacci数
本题要求实现一个计算Fibonacci数的简单函数,并利用其实现另一个函数,输出两正整数m和n(0<m≤n≤10000)之间的所有Fibonacci数。所谓Fibonacci数列就是满足任一项数字是前两项的和(最开始两项均定义为1)的数列。
函数接口定义:
int fib( int n );
void PrintFN( int m, int n );
其中函数fib
须返回第n
项Fibonacci数;函数PrintFN
要在一行中输出给定范围[m
, n
]内的所有Fibonacci数,相邻数字间有一个空格,行末不得有多余空格。如果给定区间内没有Fibonacci数,则输出一行“No Fibonacci number”。
裁判测试程序样例:
#include <stdio.h>
int fib( int n );
void PrintFN( int m, int n );
int main()
{
int m, n, t;
scanf("%d %d %d", &m, &n, &t);
printf("fib(%d) = %d\n", t, fib(t));
PrintFN(m, n);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例1:
20 100 7
输出样例1:
fib(7) = 13
21 34 55 89
输入样例2:
2000 2500 8
输出样例2:
fib(8) = 21
No Fibonacci number
思路:
int fib( int n )
{
int a=1;
int b=1;
if(n==1||n==2) return 1;
else
{
int c;
int temp=2;
while(1)
{
c=a+b;
temp++;
a=b;
b=c;
if(temp>=n) break;
}
return c;
}
}
void PrintFN( int m, int n )
{
int i;
int arr[100];
int tt=0;
for(i=1;;i++)
{
int temp=fib(i);
if(temp>=m&&temp<=n)
{
arr[tt++]=temp;
}
if(temp>n) break;
}
if(tt==0) printf("No Fibonacci number\n");
else
{
for(i=0;i<tt;i++)
{
if(i==tt-1) printf("%d\n",arr[i]);
else printf("%d ",arr[i]);
}
}
}