PAT(乙级) 题目1001-1010

2023.1.24 ☁very cold!!😊

1001 害死人不偿命的(3n+1)猜想(√)

卡拉兹(Callatz)猜想:

对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n+1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n=1。卡拉兹在 1950 年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证 (3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……

我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过 1000 的正整数 n,简单地数一下,需要多少步(砍几下)才能得到 n=1?

输入格式:
每个测试输入包含 1 个测试用例,即给出正整数 n 的值。

输出格式:
输出从 n 计算到 1 需要的步数。

输入样例:
3
输出样例:
5

思路:判断奇偶数,进行相应操作

代码如下:

#include<bits/stdc++.h>
using namespace std;

int main(){
	int n;
	cin>>n;
	
	int pos = 0;
	while(n!=1){
		if(n%2 == 0){   //为偶数时
			n = n/2; 
		}
		else{
			n = (3*n+1)/2;
		}
		pos++;
	}
	cout<<pos;
	return 0;
}

3n要写成3*n
进行算数运算时,不能出现3n+1,否则会报错:[Error] invalid suffix "n" on integer constant

n = (3*n+1)/2;

1002 写出这个数(√)

读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字。

输入格式:
每个测试输入包含 1 个测试用例,即给出自然数 n 的值。这里保证 n 小于 10^100 。

输出格式:
在一行内输出 n 的各位数字之和的每一位,拼音数字间有 1 空格,但一行中最后一个拼音数字后没有空格。

输入样例:
1234567890987654321123456789
输出样例:
yi san wu

代码如下:

#include<bits/stdc++.h>
using namespace std;

int arr[1000];    //存储算得的结果的各位数 
int main(){
	char n[101];
	cin>>n;
	
	char han[10][5] = {"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
	
	int pos = strlen(n); //表示该数有几位 
	
	
	int ans = 0;
	for(int i=0; i<pos; i++){   //计算得到各位数之和 
		ans = ans + n[i] - '0';
		//cout<<ans<<" ";
	}
	

	int x = 0;  //表示所得答案有几位 
	while(ans != 0){   //将答案的各位数存入数组 
		arr[x] = ans%10;
		x++;
		ans = ans/10;	
	}
	
	for(int i=x-1; i>=0; i--){
		cout<<han[arr[i]];		
		if(i!=0) cout<<" ";
	}
	return 0;
}

只能小数通过(T-T,我好像只能自己写成这样,先放这吧,想让小赵老师给我改一改,以后有时间再说吧)(++自己改出来啦!!!happy!!!虽然捣鼓了很久嘿嘿:

int main(){
	int n;
	cin>>n;
	
	char han[10][5] = {"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
	
	int pos = 0; //表示该数有几位 
	while(n != 0){   //将各位数存入数组 
		arr[pos] = n%10;
		pos++;
		n = n/10;	
	}
	
	int ans = 0;
	for(long long i=0; i<pos; i++){   //计算得到各位数之和 
		ans = ans + arr[i];
	}

	int x = 0;  //表示所得答案有几位 
	while(ans != 0){   //将答案的各位数存入数组 
		a[x] = ans%10;
		x++;
		ans = ans/10;	
	}
	
	for(long long i=x-1; i>=0; i--){
		cout<<han[a[i]]<<" ";		
	}
	return 0;
}

字符串数组的定义
定义字符串数组的时候,出现报错:[Error] too many initializers for 'char [10]'
char数组,一个字符串相当于一个一维的字符数组,此时字符数组的长度就是字符串的长度,多个字符串就意味着多了一个“一维数组”但这个数组里保存的是字符串,所以集合成了字符二维数组。该二维数组行定义的时候就表示字符串的个数(适当加大点容量,防止有可能发生的段错误),列是字符串的长度。

因为字符串是字面值,即常量,应该这样声明数组:

const char* numbers[] = {"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};

也可以这样声明数组:

char numbers[10][5] = {"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
	

它所做的是声明一个包含 9 个元素的二维数组,每个元素包含 6 个字符。所以现在您可以根据需要在运行时更改每个单词的值。

	while(ans != 0){   //将计算所得结果各位数存入数组 
		int x = i;
		array[x] = ans%10;
		x--;
		ans = ans/10;	
	}
	for(int j=i; j>i; j--){
		cout<<han[array[j]]<<" ";
	}

用char来表示自然数
输入要求,是一个自然数,且不超过101位,这个数过大,超过了int、long long的范围,只能通过char来定义

	char n[101];
	cin>>n;

③数据类型转换
在计算时把字符型数据转换为整型,加 - ‘0’

ans = ans + n[i] - '0';

2023.1.25 ☁ cold!!😯

1003 我要通过!

“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。

得到“答案正确”的条件是:
字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
现在就请你为 PAT 写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。

输入格式:
每个测试输入包含 1 个测试用例。第 1 行给出一个正整数 n (≤10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过 100,且不包含空格。

输出格式:
每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出 YES,否则输出 NO。

输入样例:
10
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA
APT
APATTAA
输出样例:
YES
YES
YES
YES
NO
NO
NO
NO
NO
NO

代码如下:

在这里插入代码片

不会写,😅

1004 成绩排名(√)

读入 n(>0)名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。

输入格式:
每个测试输入包含 1 个测试用例,格式为
第 1 行:正整数 n
第 2 行:第 1 个学生的姓名 学号 成绩
第 3 行:第 2 个学生的姓名 学号 成绩
… … …
第 n+1 行:第 n 个学生的姓名 学号 成绩

其中姓名和学号均为不超过 10 个字符的字符串,成绩为 0 到 100 之间的一个整数,这里保证在一组测试用例中没有两个学生的成绩是相同的。

输出格式:
对每个测试用例输出 2 行,第 1 行是成绩最高学生的姓名和学号,第 2 行是成绩最低学生的姓名和学号,字符串间有 1 空格。

输入样例:
3
Joe Math990112 89
Mike CS991301 100

Mary EE990830 95
输出样例:
Mike CS991301
Joe Math990112

思路:
定义一个结构体,包含姓名、学号、分数
头文件有点疑惑。
解决啦!
万能头文件里包含了algorithm文件,max和min是其中的一个函数,所以运行报错。

代码如下:

#include<stdio.h>

struct student
{
	char name[15];
	char ID[15];
	int grade;
}temp,max,min;  //全局变量 

int main(){
	int n;
	scanf("%d",&n);
	
	max.grade = -1;
	min.grade = 101; 
	
	while(n--){
		scanf("%s %s %d",&temp.name, &temp.ID, &temp.grade);
		if(temp.grade > max.grade){
			max = temp;
		}
		if(temp.grade < min.grade){
			min = temp;
		}
	}
	
	printf("%s %s\n",&max.name, &max.ID);
	printf("%s %s",&min.name, &min.ID); 

	return 0; 
}

C++代码如下:

#include<bits/stdc++.h>
using namespace std;

struct student
{
	char name[15];
	char ID[15];
	int grade;
}temp,da,xiao;  //全局变量 

int main(){
	int n;
	cin>>n;
	
	da.grade = -1;
	xiao.grade = 101; 
	
	while(n--){
		//scanf("%s %s %d",&temp.name, &temp.ID, &temp.grade);
		cin>>temp.name>>temp.ID>>temp.grade;
		
		if(temp.grade > da.grade){
			da = temp;
		}
		if(temp.grade < xiao.grade){
			xiao = temp;
		}
	}
	
	//printf("%s %s\n",&da.name, &da.ID);
	//printf("%s %s",&xiao.name, &xiao.ID); 

	cout<<da.name<<" "<<da.ID<<endl;
	cout<<xiao.name<<" "<<xiao.ID;
	return 0; 
}

1005 继续(3n+1)猜想

卡拉兹(Callatz)猜想已经在1001中给出了描述。在这个题目里,情况稍微有些复杂。

当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数。例如对 n=3 进行验证的时候,我们需要计算 3、5、8、4、2、1,则当我们对 n=5、8、4、2 进行验证的时候,就可以直接判定卡拉兹猜想的真伪,而不需要重复计算,因为这 4 个数已经在验证3的时候遇到过了,我们称 5、8、4、2 是被 3“覆盖”的数。我们称一个数列中的某个数 n 为“关键数”,如果 n 不能被数列中的其他数字所覆盖。

现在给定一系列待验证的数字,我们只需要验证其中的几个关键数,就可以不必再重复验证余下的数字。你的任务就是找出这些关键数字,并按从大到小的顺序输出它们。

输入格式:
每个测试输入包含 1 个测试用例,第 1 行给出一个正整数 K (<100),第 2 行给出 K 个互不相同的待验证的正整数 n (1<n≤100)的值,数字间用空格隔开。

输出格式:
每个测试用例的输出占一行,按从大到小的顺序输出关键数字。数字间用 1 个空格隔开,但一行中最后一个数字后没有空格。

输入样例:
6
3 5 6 7 8 11
输出样例:
7 6

不会写…

在这里插入代码片

1006 换个格式输出整数(√)

让我们用字母 B 来表示“百”、字母 S 表示“十”,用 12…n 来表示不为零的个位数字 n(<10),换个格式来输出任一个不超过 3 位的正整数。例如 234 应该被输出为 BBSSS1234,因为它有 2 个“百”、3 个“十”、以及个位的 4。

输入格式:
每个测试输入包含 1 个测试用例,给出正整数 n(<1000)。

输出格式:
每个测试用例的输出占一行,用规定的格式输出 n。

输入样例 1:
234
输出样例 1:
BBSSS1234
输入样例 2:
23
输出样例 2:
SS123

代码如下:

#include<bits/stdc++.h>
using namespace std;

int main(){
	int n;
	cin>>n;
	
	int ge = n % 10; 
	n = n/10;
	int shi = n%10;
	n = n/10;
	int bai = n%10;
	
	while(bai--){
		cout<<"B";
	}
	while(shi--){
		cout<<"S";
	} 
	for(int i=1; i<=ge; i++){
		cout<<i;
	}
	return 0;
} 

1007 素数对猜想(√)

在这里插入图片描述

代码如下:

#include<bits/stdc++.h>
using namespace std;
bool is_prime(int x){
	for(int i=2; i*i<=x; i++){
		if(x%i == 0) return 0;
	}
	if(x<=2) return 0;
	return 1;
}

bool is_primepair(int x){
	if(is_prime(x)){
		if(is_prime(x+2)) return 1;
		else return 0;
	}
	else return 0;
	
}
int main(){
	int n;
	scanf("%d", &n);
	
	int ans = 0;
	for(int i=1; i+2<=n; i++){  //判断条件注意i+2<=n 
		if(is_primepair(i)) ans++;
	}
	printf("%d", ans);
	return 0;
} 

1008 数组元素循环右移问题(√)

在这里插入图片描述
思路:
放入数组中
知道是循环即可,可以不进行处理,直接将所有数输出。

!M是有可能大于N的,所以需要对M模N

代码如下:

#include<bits/stdc++.h>
using namespace std;

int main(){
	int n,m;
	cin>>n>>m;
	
    m = m % n;
	int a[100];
	for(int i=0; i<n; i++){
		cin>>a[i];
	} 
	int count = 0;
	for(int i=n-m; i<n; i++){
		cout<<a[i];
		count = count + 1;
		if(count<n) cout<<" ";
	}
	
	for(int i=0; i<n-m; i++){
		cout<<a[i];
		count = count + 1;
		if(count<n) cout<<" ";
	}	

	return 0;
}

不满分代码:输出空格存在问题

#include<bits/stdc++.h>
using namespace std;

int main(){
int n,m;
cin>>n>>m;
int a[100];
for(int i=0; i<n; i++){
	cin>>a[i];
} 
for(int i=n-m; i<n; i++){
	cout<<a[i]<<" ";
}
for(int i=0; i<n-m-1; i++){
	cout<<a[i]<<" ";
}	
cout<<a[n-m-1];
return 0;
}

1009 说反话(√)

给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。

输入格式:
测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用 1 个空格分开,输入保证句子末尾没有多余的空格。

输出格式:
每个测试用例的输出占一行,输出倒序后的句子。

输入样例:
Hello World Here I Come
输出样例:
Come I Here World Hello

思路:
1、输入时不能用cin或者scanf,要用gets输入,但是gets在PAT编译器里不支持,使用cin.getline

空格和回车都可以作为数据之间的分格符,所以多个数据可以在一行输入,也可以分行输入。 但如果是字符型和字符串,则空格(ASCII 码为 32)无法用 cin 输入,字符串中也不能有空格,回车符也无法读入。

gets(s)函数与scanf(“%s”,s)相似,但不完全相同,使用scanf(“%s”,s) 函数输入字符串时存在一个问题,就是如果输入了空格会认为字符串结束,空格后的字符将作为下一个输入项处理,但gets()函数将接收输入的整个字符串直到遇到换行为止。
gets()函数:取到\n(我们输入的回车)于是停止读取,但是它不会把\n包含到字符串里面去。然而,和它配合使用的puts函数,却在输出字符串的时候自动换行。

2、利用二维数组存储一句话中的单个单词

	char temp[100][100];
	for(int i=0; i<len; i++){   //将单词分隔开存入数组temp 
		if(a[i]!=' '){
			temp[row][col++] = a[i];
		}
		else{
			temp[row][col] = '\0';  //表示字符串结束
			row = row + 1;
			col = 0; 
		}
	}

getline(a, b):第一个参数是要存储字符串的数组的名称。第二个参数是数组的大小。当 cin.getline 语句执行时,cin 读取的字符数将比该数字少一个,为 null 终止符留出空间。

3、判断某一位是否为空格要用双引号

if(a[i]!=' ')

4、'\0’表示字符串结束

temp[row][col] = '\0';  //表示字符串结束

代码如下(20分):

#include<bits/stdc++.h>
using namespace std;

int main(){
	char a[100];
	cin.getline(a,100);  //gets识别换行符结束输入 
	int len = strlen(a),row = 0,col = 0;
	char temp[100][100];
	for(int i=0; i<len; i++){   //将单词分隔开存入数组temp 
		if(a[i]!=' '){
			temp[row][col++] = a[i];
		}
		else{
			temp[row][col] = '\0';  //表示字符串结束
			row = row + 1;
			col = 0; 
		}
	}
	
	for(int i=row; i>=0; i--){
		//cout<<temp[i];
		printf("%s", temp[i]);
		if(i>0){
			//cout<<" ";
			printf(" ");
		}
	} 
	
	return 0;
} 

1010一元多项式求导

在这里插入图片描述
思路:
1、C中:while(scanf(“%d%d”,&d,&z) != EOF)
C++中:while(cin >> d>>z)

在黑框中手动输入时,系统并不知道什么时候到达了所谓的“文件末尾”,因此需要用 < Ctrl + Z > 组合键,然后按< Enter >键的方式来告诉系统已经到了 EOF,这样系统才会结束 while

循环输入,直到符合某种条件时结束输入。
cin>>s是有返回值的,只要s满足类型条件,就会return true,一直执行下去,而cin会忽略空格或者enter,因此,enter后不会结束循环。只能 ctrl+Z

其实很简单:通过 get() 判断下一个输入是不是回车就行。

while(cin>>a){
    ...
    if(cin.get()=='\n') break;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值