PTA 程序设计天梯赛(141~160题)

文章目录

    • 141、BCD解密 (10 分)
    • 142、掉入陷阱的数字 (15 分)
    • 143、简化的插入排序 (15 分)
    • 144、有理数比较 (10 分)
    • 145、计算职工工资 (15 分)
    • 146、猴子选大王 (20 分)
    • 147、逆序的三位数 (10 分)
    • 148、评分规则 (5 分)
    • 149、评委打分 (5 分)
    • 150、特殊a串数列求和 (20 分)
    • 151、换硬币 (20 分)
    • 152、高空坠球 (20 分)
    • 153、输出学生成绩 (20 分)
    • 154、求整数的位数及各位数字之和 (15 分)
    • 155、 约分最简分式 (15 分)
    • 156、我是升旗手 (10 分)
    • 157、人民币兑换 (15 分)
    • 158、两个有序序列的中位数 (25 分)
    • 159、找出总分最高的学生 (15 分)
    • 160、求给定精度的简单交错序列部分和 (15 分)

创作不易,有用请点个赞,感谢各位!

141、BCD解密 (10 分)

BCD数是用一个字节来表达两位十进制的数,每四个比特表示一位。所以如果一个BCD数的十六进制是0x12,它表达的就是十进制的12。但是小明没学过BCD,把所有的BCD数都当作二进制数转换成十进制输出了。于是BCD的0x12被输出成了十进制的18了!

现在,你的程序要读入这个错误的十进制数,然后输出正确的十进制数。提示:你可以把18转换回0x12,然后再转换回12。

输入格式:
输入在一行中给出一个[0, 153]范围内的正整数,保证能转换回有效的BCD数,也就是说这个整数转换成十六进制时不会出现A-F的数字。

输出格式:
输出对应的十进制数。

输入样例:
18
输出样例:
12

#include
int main()
{
	int n;
	int a[100000],k=0;
	int i,j;
	scanf("%d",&n);
	if(n==0)
	{
	  printf("0");
	  return 0;
	}
	while(n!=0)
	{
		a[k++]=n%16;
		n/=16;
	}
	for(i=k-1;i>=0;i--)
		printf("%d",a[i]);
}

142、掉入陷阱的数字 (15 分)

对任意一个自然数N
​0
​​ ,先将其各位数字相加求和,再将其和乘以3后加上1,变成一个新自然数N
​1
​​ ;然后对N
​1
​​ 重复这种操作,可以产生新自然数N
​2
​​ ;……多次重复这种操作,运算结果最终会得到一个固定不变的数N
​k
​​ ,就像掉入一个数字“陷阱”。

本题要求对输入的自然数,给出其掉入“陷阱”的过程。

输入格式:
在一行内给出一个自然数N
​0
​​ (N
​0
​​ <30000)。

输出格式:
对于输入的N
​0
​​ ,逐行输出其掉入陷阱的步骤。第i行描述N掉入陷阱的第i步,格式为: i:N
​i
​​ (i≥1)。当某一步得到的自然数结果N
​k
​​ (k≥1)与上一步N
​k−1
​​ 相同时,停止输出。

输入样例:
5
输出样例:
1:16
2:22
3:13
4:13

#include
int number(int N);
int main (){
   int N=0,count=0,now=0,pre=0;
   scanf("%d",&N);
   now = number(N);
    while(1){
        count++;
        printf("%d:%d\n",count,now);
        pre=now;
        now=number(now);
        if(pre==now){
          if(now!=N)//如果这个数的最终结果和N相等,则不用再输出
            printf("%d:%d\n",count+1,now);
            break;
      }
  }
   return 0;
}
int number(int N){
    int add=0,num=N%10;
    if(num==N){
        add=N;
    }else{
        while(N!=0){
        add+=num;
        N/=10;
        num=N%10;
        }
    }
    return add*3+1;
}

143、简化的插入排序 (15 分)

本题要求编写程序,将一个给定的整数插到原本有序的整数序列中,使结果序列仍然有序。

输入格式:
输入在第一行先给出非负整数N(<10);第二行给出N个从小到大排好顺序的整数;第三行给出一个整数X。

输出格式:
在一行内输出将X插入后仍然从小到大有序的整数序列,每个数字后面有一个空格。

输入样例:
5
1 2 4 5 7
3
输出样例:
1 2 3 4 5 7

#include
#include
#include
int comp(const void* a,const void* b)
{
	return *(int*)a - *(int*)b;
}
int main()
{
	int i;
	int a[12];
	int n;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	scanf("%d",&a[n]);
	qsort(a,n+1,sizeof(a[0]),comp);
	for(i=0;i<n+1;i++)
	printf("%d ",a[i]);
}

144、有理数比较 (10 分)

本题要求编写程序,比较两个有理数的大小。

输入格式:
输入在一行中按照“a1/b1 a2/b2”的格式给出两个分数形式的有理数,其中分子和分母全是整形范围内的正整数。

输出格式:
在一行中按照“a1/b1 关系符 a2/b2”的格式输出两个有理数的关系。其中“>”表示“大于”,“<”表示“小于”,“=”表示“等于”。

输入样例1:
1/2 3/4
输出样例1:
1/2 < 3/4
输入样例2:
6/8 3/4
输出样例2:
6/8 = 3/4

#include
#include
#include
int main()
{
	int a1,b1,a2,b2;
	double sum1,sum2;
	scanf("%d/%d %d/%d",&a1,&b1,&a2,&b2);
	sum1 = a1*1.0/b1;
	sum2 = a2*1.0/b2;
	if(sum1>sum2)
	printf("%d/%d > %d/%d\n",a1,b1,a2,b2);
	else if(sum1 == sum2)
	printf("%d/%d = %d/%d\n",a1,b1,a2,b2);
	else
	printf("%d/%d < %d/%d\n",a1,b1,a2,b2);
}

145、计算职工工资 (15 分)

给定N个职员的信息,包括姓名、基本工资、浮动工资和支出,要求编写程序顺序输出每位职员的姓名和实发工资(实发工资=基本工资+浮动工资-支出)。

输入格式:
输入在一行中给出正整数N。随后N行,每行给出一位职员的信息,格式为“姓名 基本工资 浮动工资 支出”,中间以空格分隔。其中“姓名”为长度小于10的不包含空白字符的非空字符串,其他输入、输出保证在单精度范围内。

输出格式:
按照输入顺序,每行输出一位职员的姓名和实发工资,间隔一个空格,工资保留2位小数。

输入样例:
3
zhao 240 400 75
qian 360 120 50
zhou 560 150 80
输出样例:
zhao 565.00
qian 430.00
zhou 630.00

#include
#define N 1000
struct yuan
{
  char name[11];
  double z1;//如果这里用int型,则显示错误
  double z2;
  double z3;
  double sum
}ren[N];
int main()
{
  int n,i;
  scanf("%d",&n);
  for(i=0;i<n;i++)
  {
    scanf("%s %lf %lf %lf",ren[i].name,&ren[i].z1,&ren[i].z2,&ren[i].z3);
    ren[i].sum=ren[i].z1+ren[i].z2-ren[i].z3;
  }
  for(i=0;i<n;i++)
  {
       printf("%s %.2lf\n",ren[i].name,ren[i].sum);
  }
  return 0;
}

146、猴子选大王 (20 分)

一群猴子要选新猴王。新猴王的选择方法是:让N只候选猴子围成一圈,从某位置起顺序编号为1~N号。从第1号开始报数,每轮从1报到3,凡报到3的猴子即退出圈子,接着又从紧邻的下一只猴子开始同样的报数。如此不断循环,最后剩下的一只猴子就选为猴王。请问是原来第几号猴子当选猴王?

输入格式:
输入在一行中给一个正整数N(≤1000)。

输出格式:
在一行中输出当选猴王的编号。

输入样例:
11
输出样例:
7

#include
int sum=0,i;
int funtion(int x,int y)	//x = 11, y = 3
{
	for(i=y-1;i<=x;i++)		//根据数学规律,应从i的初始值 = 报的特殊数-1 
	{						//每次一到3的倍数时,sum=0,然后重新进行计算
		sum = (sum+3)%i;	//sum+特殊数%i 
	}
	return sum;
}
int main()
{
	int i,n,sum=0;
	scanf("%d",&n);
	printf("%d",funtion(n,3)+1);
}

147、逆序的三位数 (10 分)

程序每次读入一个正3位数,然后输出按位逆序的数字。注意:当输入的数字含有结尾的0时,输出不应带有前导的0。比如输入700,输出应该是7。

输入格式:
每个测试是一个3位的正整数。

输出格式:
输出按位逆序的数。

输入样例:
123
输出样例:
321

#include
#include
#include
int main()
{
	int n;
	int i,j;
	int a[3];
	int flag=-1;
	scanf("%d",&n);
	for(i=0;i<3;i++)
	{
		a[i]=n%10;
		n/=10;
	}
	for(i=0;i<3;i++)
	{
		if(a[i]!=0)
			flag=1;
		if(flag!=-1)
		{
			printf("%d",a[i]);
		}
		else if(a[i]!=0)
		{
			printf("%d",a[i]);
		}
	}
}

148、评分规则 (5 分)

小明与伙伴们游戏,请来了5个裁判。对于每个孩子的表现,每个裁判给一个分数。总评分的计算规则是:去掉最高分,去掉最低分,剩下的分数计算平均分,作为总评分。请你帮小明编写程序计算总评分。

输入格式:
在一行中给出5个在0到100之间的整数,用一个空格隔开。这个5个整数已经按照从大到小顺序排好了。

输出格式:
在一行中输出总评分,要求保留小数点后2位。

输入样例:
100 99 98 97 96
输出样例:
98.00

#include
#include
#include
int comp(const void*a ,const void*b)
{
	return *(int*)a - *(int*)b;
}
int main()
{
	int a[5];
	int i,j;
	for(i=0;i<5;i++)
	{
		scanf("%d",&a[i]);
	}
	qsort(a,5,sizeof(a[0]),comp);
	a[0]=0;
	a[4]=0;
	double avg = (a[1]+a[2]+a[3])/3;
	printf("%.2lf\n",avg);
}

149、评委打分 (5 分)

班级里要搞智力竞赛啦!同学们都踊跃参加。进入最后决赛的是10个同学,随着一道道题目的出示,有时是1号选手得分,有时是5号选手得分,每次答对者得10分,最后结果如何呢?

输入格式:
第一行有十个整数,表示十位同学的初始分。第二行一个整数n,表示有n道题竞赛。 接下去有n行,每行有一个数字x,x表示本次可以加分的选手序号(每次答对者得10分)。

输出格式:
10个同学最终的得分值,每两位同学之间有一个空格。

输入样例:
10 0 0 0 10 10 0 0 0 10
3
1
10
1
输出样例:
30 0 0 0 10 10 0 0 0 20

#include
#include
#include
int main()
{
	int i,j;
	int a[10];
	for(i=0;i<10;i++)
	scanf("%d",&a[i]);
	int n;
	int b;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%d",&b);
		a[b-1]+=10;
	}
	for(i=0;i<10;i++)
	{
		if(i==10-1)
		printf("%d",a[i]);
		else
		printf("%d ",a[i]);
	}
}

150、特殊a串数列求和 (20 分)

给定两个均不超过9的正整数a和n,要求编写程序求a+aa+aaa++⋯+aa⋯a(n个a)之和。

输入格式:
输入在一行中给出不超过9的正整数a和n。

输出格式:
在一行中按照“s = 对应的和”的格式输出。

输入样例:
2 3
输出样例:
s = 246

#include
#include
int main()
{
	int a,n;
	scanf("%d%d",&a,&n);
	int i,j;
	int t=a;
	int sum=a;
	for(i=1;i<n;i++)
	{
			t = a*(pow(10,i))+t;
			//printf("%d\n",t);
			sum+=t;
	}
	printf("s = %d\n",sum);
}

151、换硬币 (20 分)

将一笔零钱换成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
#include
int main()
{
	int i,j,k;
	int n;
	int t=0;
	scanf("%d",&n);
	for(i=n/5;i>=1;i--)
	{
		for(j=n/2;j>=1;j--)
		{
			for(k=n;k>=1;k--)
			{
				if(i*5+j*2+k==n)
				{
					t++;
					printf("fen5:%d, fen2:%d, fen1:%d, total:%d\n",i,j,k,i+j+k);
				}
			}
		}
	}
	printf("count = %d\n",t);
}

152、高空坠球 (20 分)

皮球从某给定高度自由落下,触地后反弹到原高度的一半,再落下,再反弹,……,如此反复。问皮球在第n次落地时,在空中一共经过多少距离?第n次反弹的高度是多少?

输入格式:
输入在一行中给出两个非负整数,分别是皮球的初始高度和n,均在长整型范围内。

输出格式:
在一行中顺序输出皮球第n次落地时在空中经过的距离、以及第n次反弹的高度,其间以一个空格分隔,保留一位小数。题目保证计算结果不超过双精度范围。

输入样例:
33 5
输出样例:
94.9 1.0

#include
int main()
{
	double m;	//初始高度
	int n;	//第n次反弹的高度
	scanf("%lf%d",&m,&n);
	double sum=m;
	if(m==0 || n==0)
	{
	  printf("0.0 0.0\n");
	  return 0;
	}
	for(int i=2;i<=n;i++)
	{
		sum+=m;
		m/=2;
	//	printf("m = %lf sum = %lf\n",m,sum);
	}
	m/=2;
	printf("%.1lf %.1lf\n",sum,m);
}

153、输出学生成绩 (20 分)

本题要求编写程序,根据输入学生的成绩,统计并输出学生的平均成绩、最高成绩和最低成绩。建议使用动态内存分配来实现。

输入格式:
输入第一行首先给出一个正整数N,表示学生的个数。接下来一行给出N个学生的成绩,数字间以空格分隔。

输出格式:
按照以下格式输出:

average = 平均成绩
max = 最高成绩
min = 最低成绩
结果均保留两位小数。

输入样例:
3
85 90 95
输出样例:
average = 90.00
max = 95.00
min = 85.00

#include 
#include 
 
int main()
{	
    int n,i;
    int *p; 
    float sMax,sMin,sSum =0;
    float sAvg;
    scanf("%d",&n); 
	//开启n个int的字节长度 
    p = (int *)malloc(sizeof(int) * n);
    for(i=0;i<n;i++)
    {
    	scanf("%d",p+i);
    	//如果是首个元素,就把首个元素同时赋值给最大最小值 
    	if(i == 0)
    	{
    		sMax = *(p+i);
    		sMin =  *(p+i);	
        }else
	    {
	    	if( *(p+i) > sMax)
	       		sMax =  *(p+i);
		    if( *(p+i) < sMin)
	        	sMin =  *(p+i);
	    }
	    sSum +=  *(p+i);
    }
	printf("average = %.2lf\n",sSum/n);
	printf("max = %.2lf\n",sMax);
	printf("min = %.2lf\n",sMin);
}

154、求整数的位数及各位数字之和 (15 分)

对于给定的正整数N,求它的位数及其各位数字之和。

输入格式:
输入在一行中给出一个不超过10
​9
​​ 的正整数N。

输出格式:
在一行中输出N的位数及其各位数字之和,中间用一个空格隔开。

输入样例:
321
输出样例:
3 6

#include
#include

int main()
{
	int n;
	int k=0;
	int sum=0;
	scanf("%d",&n);
	while(n!=0)
	{
		sum+=n%10;
		n/=10;
		k++;
	}
	printf("%d %d\n",k,sum);
}

155、 约分最简分式 (15 分)

分数可以表示为分子/分母的形式。编写一个程序,要求用户输入一个分数,然后将其约分为最简分式。最简分式是指分子和分母不具有可以约分的成分了。如6/12可以被约分为1/2。当分子大于分母时,不需要表达为整数又分数的形式,即11/8还是11/8;而当分子分母相等时,仍然表达为1/1的分数形式。

输入格式:
输入在一行中给出一个分数,分子和分母中间以斜杠/分隔,如:12/34表示34分之12。分子和分母都是正整数(不包含0,如果不清楚正整数的定义的话)。

提示:在scanf的格式字符串中加入/,让scanf来处理这个斜杠。

输出格式:
在一行中输出这个分数对应的最简分式,格式与输入的相同,即采用分子/分母的形式表示分数。如 5/6表示6分之5。

输入样例:
66/120
输出样例:
11/20

#include
int gcd(int a,int b){
    /*if(a 
    int r=a%b;
    while(r){
        a=b;
        b=r;
        r=a%b;
    } 
    return b;
}
int main(){
    int a,b;
    scanf("%d/%d",&a,&b);
    int n=gcd(a,b);
    printf("%d/%d",a/n,b/n);
} 

156、我是升旗手 (10 分)

一年一度的升旗手选拔又要到了,学校要求每个班级选出一位同学做升旗手的候选人。因 为升旗手对身高有严格的要求,所以班主任决定选班级里个子最高的同学(如果两位同学 一样高,则选任意一位)。你能很快地给老师答案么?

输入格式:
输入包括两行。 第一行:包括一个整数n,表示班级里共有n位同学。 第二行:包含n个三位数,表示每一位同学的身高。

输出格式:
输出身高最高的同学的身高。

输入样例:
4
130 125 129 140
输出样例:
140

#include
#include

int main()
{
	int max=0;
	int n;
	int x;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&x);
		if(max<x)
			max=x;
	 } 
	 printf("%d\n",max);
}

157、人民币兑换 (15 分)

1元5角钱人民币兑换5分、2分和1分的硬币(每一种都要有)共100枚,会有很多种兑换方案。请编写程序给出各种兑换方案。

输入格式:
输入为一个正整数n,表示要求输出前n种可能的方案。方案的顺序,是按照5分硬币从少到多排列的。

输出格式:
显示前n种方案中5分、2分、1分硬币各多少枚。每行显示一种方案,数字之间空一格,最后一个数字后没有空格。

注意:如果全部方案不到n种,就顺序输出全部可能的方案。

输入样例:
5
输出样例:
1 46 53
2 42 56
3 38 59
4 34 62
5 30 65

#include
int main()
{
	int i,j,k;
	int wu,er,san;
	int n;
	int t=0;
	scanf("%d",&n);
	for(i=1;i<=150/5;i++)		//5分一个,150分就有30个 
	{
		for(j=1;j<=150/2;j++)	//2分一个,150分就有75个 
		{
			for(k=1;k<=100;k++)	//因为硬币不能多于100枚,所以1分的情况最多只有100个 
			{
				if(i*5+j*2+k==150 && i+j+k==100 && t<n)	//题目要求说输出n种可能的方案,所以输入到n种就可以了 
				{
					printf("%d %d %d\n",i,j,k);
					t++;	//每有一种方案就+1,最多n种 
				}
			}
		}
	}
}

158、两个有序序列的中位数 (25 分)

已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A
​0
​​ ,A
​1
​​ ,⋯,A
​N−1
​​ 的中位数指A
​(N−1)/2
​​ 的值,即第⌊(N+1)/2⌋个数(A
​0
​​ 为第1个数)。

输入格式:
输入分三行。第一行给出序列的公共长度N(0

输出格式:
在一行中输出两个输入序列的并集序列的中位数。

输入样例1:
5
1 3 5 7 9
2 3 4 5 6
输出样例1:
4
输入样例2:
6
-100 -10 1 1 1 1
-50 0 2 3 4 5
输出样例2:
1

#include
#include
#include
int comp(const void* a,const void* b)
{
	return *(int*)b - *(int*)a;
}
int main()
{
	int i;
	int n;
	int a[1000001];
	scanf("%d",&n);
	for(i=0;i<n*2;i++)
	{
		scanf("%d",&a[i]);
	}
	qsort(a,n*2,sizeof(a[0]),comp);
	printf("%d\n",a[n]);
	return 0;
}

159、找出总分最高的学生 (15 分)

给定N个学生的基本信息,包括学号(由5个数字组成的字符串)、姓名(长度小于10的不包含空白字符的非空字符串)和3门课程的成绩([0,100]区间内的整数),要求输出总分最高学生的姓名、学号和总分。

输入格式:
输入在一行中给出正整数N(≤10)。随后N行,每行给出一位学生的信息,格式为“学号 姓名 成绩1 成绩2 成绩3”,中间以空格分隔。

输出格式:
在一行中输出总分最高学生的姓名、学号和总分,间隔一个空格。题目保证这样的学生是唯一的。

输入样例:
5
00001 huanglan 78 83 75
00002 wanghai 76 80 77
00003 shenqiang 87 83 76
10001 zhangfeng 92 88 78
21987 zhangmeng 80 82 75
输出样例:
zhangfeng 10001 258

#include
struct Student{
	char xuehao[7];
	char name[12];
	int sum;
}love[100];
int comp(const void* a,const void* b)
{
	struct Student *aa = (struct Student *)a;
	struct Student *bb = (struct Student *)b;
	
	return ((bb->sum) - (aa->sum));	//根据总分从大到小排序学生信息库 
}
int main()
{
	int i,j;
	int n;
	int one,two,three;
	scanf("%d",&n);
	getchar();
	for(i=0;i<n;i++)
	{
		scanf("%s%s%d%d%d",&love[i].xuehao,&love[i].name,&one,&two,&three);
		love[i].sum = one+two+three;	//直接存总分就行 
	}
	qsort(love,n,sizeof(love[0]),comp);
	printf("%s %s %d\n",love[0].name,love[0].xuehao,love[0].sum);
}

160、求给定精度的简单交错序列部分和 (15 分)

本题要求编写程序,计算序列部分和 1 - 1/4 + 1/7 - 1/10 + … 直到最后一项的绝对值不大于给定精度eps。

输入格式:
输入在一行中给出一个正实数eps。

输出格式:
在一行中按照“sum = S”的格式输出部分和的值S,精确到小数点后六位。题目保证计算结果不超过双精度范围。

输入样例1:
4E-2
输出样例1:
sum = 0.854457
输入样例2:
0.02
输出样例2:
sum = 0.826310

#include
int main()
{
	int i=0,j;		//循环 
	int flag = 1;	//控制偶数位正,奇数为负 
	int zi=1,mu=1;
	double a,b,sum=0;
	scanf("%lf",&a);
	do
	{
		b = zi*1.0/mu;	//这里要注意无理数的情况,所以要用浮点型计算,要*1.0 
		sum+=b*flag;	//对这个序列每次循环都进行求和,直到序列值b<=a时跳出循环 
		flag=-flag;		//-正数 = 负数,-负数 = 正数 
		mu+=3;			//分子不变,分母每次比上一次多3 
	}while(b>a);		//不大于的意思就是:不能等于也不能小鱼 
	printf("sum = %lf\n",sum);
}

创作不易,有用请点个赞,感谢各位!

你可能感兴趣的:(PTA,PTA,王睿丶,题库,程序设计天梯赛)