PTA(01)典例详解

目录

7-1 然后是几点

 7-2 逆序的三位数

 7-4 掉入陷阱的数字

 7-15 冠军魔术

 7-21 英文字母替换加密(大小写转换+后移1位)

 7-46 计算存款利息

 7-49 BCD解密

 7-54 Wifi密码


7-1 然后是几点

有时候人们用四位数字表示一个时间,比如 1106 表示 11 点零 6 分。现在,你的程序要根据起始时间和流逝的时间计算出终止时间。

读入两个数字,第一个数字以这样的四位数字表示当前时间,第二个数字表示分钟数,计算当前时间经过那么多分钟后是几点,结果也表示为四位数字。当小时为个位数时,没有前导的零,例如 5 点 30 分表示为 530;0 点 30 分表示为 030。注意,第二个数字表示的分钟数可能超过 60,也可能是负数。

输入格式:

输入在一行中给出 2 个整数,分别是四位数字表示的起始时间、以及流逝的分钟数,其间以空格分隔。注意:在起始时间中,当小时为个位数时,没有前导的零,即 5 点 30 分表示为 530;0 点 30 分表示为 030。流逝的分钟数可能超过 60,也可能是负数。

输出格式:

输出不多于四位数字表示的终止时间,当小时为个位数时,没有前导的零。题目保证起始时间和终止时间在同一天内。

输入样例:

1120 110

输出样例:

1310

 该题有两个注意点,将(1)时间转化为分钟数相加最后再转换回时间(2)自动补0,比如0 点 30 分表示为 030

 这个我的思路就是先将给出的时间分别除100和取余100,分离出小时与分钟,然后再全部转化为分钟,加上流逝的分钟再分别除60和取余60,分离出小时和分钟,同时输出即可。其次就是补零,我们使用%02d即可使其不足两位数自动补零,下面给出代码

#include <stdio.h>
int main()
{
	int a,b,c,d,f,g;
	scanf("%d %d",&a,&b);
	c=a/100*60;
	d=a%100;
	f=(b+c+d)/60;
	g=(b+c+d)%60;
	printf("%d%02d",f,g);
    return 0;
}

 7-2 逆序的三位数

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

输入格式:

每个测试是一个3位的正整数。

输出格式:

输出按位逆序的数。

输入样例:

123

输出样例:

321

这道题的思路也是通过除和取余分离出每一位数,然后再进行组合进行逆向输出,代码如下

#include <stdio.h>
int main ()
{
    int x;
    int a,b,c,d;
    scanf("%d",&x);
    a = x%10;
    b = x/10%10;
    c = x/100;
    d = a*100+b*10+c;
    printf("%d",d);
    return 0;
}

 7-4 掉入陷阱的数字

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

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

输入格式:

在一行内给出一个自然数N0​(N0​<30000)。

输出格式:

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

输入样例:

5

输出样例:

1:16
2:22
3:13
4:13

 这道题首先我的思路是定义出一个能够失去各位数字相加求和的函数,方便我们后来的计算

定义出n1,n2, n1=n2时停止输出,否则使其一直输出,使用i累加计数,代码如下

#include<stdio.h>
int add(int a);// 函数的定义,函数作用:将各位数字相加求和
int main(void)
{	
	int n2;
	scanf("%d",&n2);
	int n1 = 0;
	int i =0;
	while(n1!=n2){
		i++;
		n1 = add(n2)*3+1;
		printf("%d:%d\n",i,n1);
		if(n1==n2){  //这个if判断当n1等于n2时就不要把下一个输出,不然会出现三个一样的 
			break;
		}
		n2 = add(n1)*3+1; 使n1!=n2从而继续输出
		i++;
		printf("%d:%d\n",i,n2);
		
	}
 
	return 0;
}
int add(int a){  //求各位和函数
	int sum = 0;
	int n =0;
	while(a>0){
		n=a%10;	
		a=a/10;
		sum+=n;
	}
	return sum;
}

 7-15 冠军魔术

2018年FISM(世界魔术大会)近景总冠军简纶廷的表演中有一个情节:以桌面上一根带子为界,当他将纸牌从带子的一边推到另一边时,纸牌会变成硬币;把硬币推回另一边会变成纸牌。

这里我们假设纸牌会变成等量的硬币,而硬币变成纸牌时,纸牌的数量会加倍。那么给定纸牌的初始数量,当他来回推了 N 次(来/回各算一次)后,手里拿的是纸牌还是硬币?数量是多少?

输入格式:

输入在一行里给出两个正整数,分别是纸牌的初始数量和魔术师推送的次数。这里假设初始状态下魔术师手里全是纸牌。

输出格式:

如果最后魔术师手里是纸牌,输出 0 和纸牌数量;如果是硬币,则输出 1 和硬币数量。数字间须有 1 个空格。题目保证结果数值不超出整型范围(即 231−1)。

输入样例 1:

3 7

输出样例 1:

1 24

输入样例 2:

8 4

输出样例 2:

0 32

 阅读题目可知,偶数手里是纸牌奇数是硬币,而翻倍可用2的n/2次方算出,代码如下:

#include<stdio.h>
#include<math.h>
int main()
{
    int x,y,N,a;                          
    scanf("%d %d",&x,&N);
    if(N%2==0)
    {
        printf("0 %d",a=x*pow(2,N/2));
    }
    else
    {
        printf("1 %d",a=x*pow(2,(N-1)/2));
    }
               return 0;
}

 7-21 英文字母替换加密(大小写转换+后移1位)

本题要求编写程序,将英文字母替换加密。为了防止信息被别人轻易窃取,需要把电码明文通过加密方式变换成为密文。变换规则是:将明文中的所有英文字母替换为字母表中的后一个字母,同时将小写字母转换为大写字母,大写字母转换为小写字母。例如,字母a->B、b->C、…、z->A、A->b、B->c、…、Z->a。输入一行字符,将其中的英文字母按照以上规则转换后输出,其他字符按原样输出。

输入格式:

输入一行字符,以回车符 '\n'作为 结束符。

输出格式:

将输入的一行字符中的所有英文字母替换为字母表中的后一个字母,同时将小写字母转换为大写字母,大写字母转换为小写字母后输出,其他字符按原样输出。

输入样例:

在这里给出一组输入。例如:

Reold  Z123?

输出样例:

在这里给出相应的输出。例如:

sFPME  a123?

 这道题用到了ASCII码,其次还有用for循环表示“如果不回车则一直循环”,首先将输出的字符分为两类,大写字母和小写字母,再使用ASCII码使其转换,代码如下:

#include<stdio.h>
int main(void)
{
	char word=0;
	for(;(word=getchar())!='\n';)//不回车则一直循环
	{
		if('A'<=word&&word<'Z')word=word+1+32;
		else if(word=='Z')word=word-25+32;
		else if('a'<=word&&word<'z')word=word+1-32;
		else if(word=='z')word=word-25-32;
		printf("%c",word);	
	}
	printf("\n");
	return 0;
} 

 7-46 计算存款利息

本题目要求计算存款利息,计算公式为interest=money×(1+rate)year−money,其中interest为存款到期时的利息(税前),money是存款金额,year是存期,rate是年利率。

输入格式:

输入在一行中顺序给出三个正实数money、year和rate,以空格分隔。

输出格式:

在一行中按“interest = 利息”的格式输出,其中利息保留两位小数。

输入样例:

1000 3 0.025

输出样例:

interest = 76.89

这道题我们在做pta的时候总是莫名奇妙扣分,这里讲一下规范规则,首先要注意正实数,大家一定要设置成double类型,其次就是利息保留两位小数,使用.2f(注意空格)

 7-49 BCD解密

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

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

输入格式:

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

输出格式:

输出对应的十进制数。

输入样例:

18

输出样例:

12

 简单的十六进制转换为十进制,代码如下

#include<stdio.h>
int main()
{
	int n;
	int a;
	scanf("%d",&n);
	a=n%16+(n/16)*10;
	printf("%d",a);
	return 0;
}

 7-54 Wifi密码

下面是微博上流传的一张照片:“各位亲爱的同学们,鉴于大家有时需要使用 wifi,又怕耽误亲们的学习,现将 wifi 密码设置为下列数学题答案:A-1;B-2;C-3;D-4;请同学们自己作答,每两日一换。谢谢合作!!~”—— 老师们为了促进学生学习也是拼了…… 本题就要求你写程序把一系列题目的答案按照卷子上给出的对应关系翻译成 wifi 的密码。这里简单假设每道选择题都有 4 个选项,有且只有 1 个正确答案。

输入格式:

输入第一行给出一个正整数 N(≤ 100),随后 N 行,每行按照 编号-答案 的格式给出一道题的 4 个选项,T 表示正确选项,F 表示错误选项。选项间用空格分隔。

输出格式:

在一行中输出 wifi 密码。

输入样例:

8
A-T B-F C-F D-F
C-T B-F A-F D-F
A-F D-F C-F B-T
B-T A-F C-F D-F
B-F D-T A-F C-F
A-T C-F B-F D-F
D-T B-F C-F A-F
C-T A-F B-F D-F

输出样例:

13224143

 01的压轴题 我仔细讲一下需要用到的知识点

getchar() - 字符输入函数,没有参数,从输入缓冲区里面读取一个字符

缓冲区本质是一段连续的空间,比如char a[10],a为一段连续的20字节的空间

scanf等输入函数在缓冲区中获取数据,并存储在变量里 

这里我给出代码逐行给出注释吧

#include<stdio.h>
int main()
{
	int n;
	scanf("%d",&n);//读入行数
	getchar();//getchar() - 字符输入函数,没有参数,从输入缓冲区里面读取一个字符
	char a='0',b='0',c='0';//初始化字符
	int i,j,num[n];
	for(i=0;i<n;i++)//i计数
	{
	  
	  for(j=0;j<4;j++)//四个选项,所以是小于4
	  {
		  scanf("%c",&a);//读入选项
	  	c=getchar();
	  	scanf("%c",&b);//读入T或者F
	  	
	  	if(b=='T') 
		  {
		  num[i]=a-'A'+1;//此处讲对应选项对应的T转换为密码
	}
	c=getchar();//用于读走空格和行未的换行符
} 
	}
	for(i=0;i<n;i++) printf("%d",num[i]);//i在循环外同步进行计数,输出对应的密码
	return 0;
}

最后一题我也是一知半解 很多都是个人的理解 只供参考欢迎补充 

 

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nuc-不晚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值