PAT (Basic Level) Practice 题解代码 - II(1101-1125)

PAT (Basic Level) Practice - II 1101-1125(已更新至最新!)


更多详见>>
OJ题解系列 目录导航帖


题目传送门

PAT乙级1101-1125


这里是PAT乙级考试真题的第二部分(1101-1125)
首先总结一下PAT乙级考试的常考内容:
1.模拟:根据题目的描述/步骤,模拟题目的步骤编写算法
2.程序结构类:考察分支、循环、选择语句,如分段函数、分段计价、遍历数组
3.基础算法类:贪心、数论、枚举、排序等,一般情况下主要考察这几类,难度不会特别大,需注意算法的细节,对特殊数据的处理。
4.基础数据结构:主要就两种——数组和链表(静态或动态)、栈和队列
5.C++的STL模板类:简单了解stack,queue,priority_queue,map,vector,string,pair的用法

接下来就是题解部分了,每道算法题都标注有对应的算法标签,对于那些易错、较难或是测试点比较特殊的题目会着重标注,本章推荐的题目有:

1104 天长地久 (20 分) 数论 + 枚举
1109 擅长C (20 分) 字符串 + 模拟
1115 裁判机(25分) 模拟
1123 舍入 (20 分) 字符串 + 输入/输出格式

最后,希望大家都能在PAT乙级考试中取得自己理想的成绩!


1101 B是A的多少倍 (15 分)

算法标签: 模拟
注意点: 截取D位,拼接到高位,然后将高位的数字移动到低位,新数除以原数,可得结果

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

int main(){
   
	int A;
	int D;
	scanf("%d%d",&A,&D);
	int A1 = A;
	int cnt1 = 0;
	while(A1){
   
		A1/=10;
		cnt1++;
	}
	D = D % cnt1;
	if(D==0){
   
		printf("1.00\n");
		return 0;
	}
	int cnt2 = 1;
	for(int i=0;i<D;i++){
   
		cnt2 *= 10;
	}
	A1 = 1;
	for(int i=0;i<cnt1-D;i++){
   
		A1 = A1*10;
	}
	
	A1 = (A%cnt2)*A1;
	A1 += (A/cnt2);
	double res = 1.0*A1/(1.0*A);
	printf("%.2lf\n",res);
	
	return 0;
} 

1102 教超冠军卷 (20 分)

算法标签: 排序
注意点: 遍历每条信息,记录销售量和销售额的最大值及ID号,输出结果

#include<bits/stdc++.h>
using namespace std;
char s1[20];
char s2[20];
int max_sale = -1;
int max_amount = -1;

int main(){
   
	int N;
	scanf("%d",&N);
	for(int i=0;i<N;i++){
   
		char s[20];
		scanf("%s",s);
		int sale,amount;
		scanf("%d%d",&sale,&amount);
		if(sale*amount>max_sale){
   
			max_sale = sale*amount;
			strcpy(s1,s);
		}
		if(amount>max_amount){
   
			max_amount = amount;
			strcpy(s2,s);
		} 
	}	
	printf("%s %d\n",s2,max_amount);
	printf("%s %d\n",s1,max_sale);
	return 0;
} 

1103 缘分数 (20 分)

算法标签: 枚举法
注意点: 枚举所有可能的数A和B,若满足题目中的条件,就输出结果

#include<bits/stdc++.h>
using namespace std;
int res1[10005];
int res2[10005];
int cnt = 0;
int main(){
   
	int m,n;
	scanf("%d%d",&m,&n);
	for(int a=m;a<=n;a++){
   
		for(int b=2;b<=sqrt(2*a);b++){
   
			if(a*a*a-(a-1)*(a-1)*(a-1) == (b*b+(b-1)*(b-1))*(b*b+(b-1)*(b-1))){
   
				res1[cnt] = a;
				res2[cnt++] = b;
			}
		}
	} 
	if(cnt){
   
		for(int i=0;i<cnt;i++){
   
			printf("%d %d\n",res1[i],res2[i]);
		}
	}else{
   
		printf("No Solution\n"); 
	}
	return 0;
} 

1104 天长地久 (20 分)

算法标签: 数论 + 枚举法
注意点: 本题很棒,值得反复练习
m 与 n 的最大公约数是一个大于 2 的素数,意味着m只能是末尾带有9的数字,否则不满足最大公约数>2,如gcd(15,16)=1,因此只要从末尾9的个数出发,依次枚举即可得到结果,最后排序输出。

#include<iostream>
#include<math.h>
#include<string>
using namespace std;


int isPrime(int n) {
   
	if (n <= 1)
		return 0;
	for (int i = 2; i <= sqrt(n); i++) {
   
		if (n%i == 0)
			return 0;
	}
	return 1;
}

int gcd(int a, int b) {
   
	if (b == 0)
		return a;
	else
		return gcd(b, a%b);
}

int digit(int n) {
   
	string a = to_string(n);
	int sum = 0;
	for (int i = 0; i < a.length(); i++) {
   
		sum = sum + a[i] - '0';
	}
	return sum;
}

int find_min(int nine, int k) {
   
	string a;
	for (int i = 0; i < k; i++) {
   
		if (i == 0)
			a = "1";
		else
			a += "0";
	}
	for (int i = k - 1; i >= k - nine; i--)
		a[i] = '9';
	return stoi(a);
}

int Hash[200];

int main() {
   
	int n;
	scanf("%d", &n);
	int k, m;
	int com;
	for (int i = 1; i <= n; i++) {
   
		scanf("%d%d", &k, &m);
		printf("Case %d\n", i);
		int flag = 0;
		if (m <= 9 * k) {
   
			for (int j = 3; j < m; j++) {
   
				int d = gcd(j, m);
				if (isPrime(d) && d > 2) {
   
					if ((m - j + 1) % 9 == 0) {
   
						int nine = (m - j + 1) / 9;
						int least = find_min(nine, k);
						int maxn = pow(10, k);
						for (int t = least; t < maxn; t+=pow(10,nine) ){
   
							if (digit(t) == m && digit(t + 1) == j) {
   
								flag = 1;
								printf("%d %d\n", j, t);
							}
						}
					}
				}
			}
		}
		if (flag == 0)
			printf("No Solution\n");
	}
	return 0;
}

1105 链表合并 (25 分)

算法标签: 链表 + 模拟
注意点: 此类题目可用数组模拟静态链表,遍历链表是常考点。每隔2个数合并A,每隔一个数合并B,直到链表末尾

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
map<int,int> next1;
map<int,int> value1;
int a_value[maxn];
int a_add[maxn];
int b_value[maxn];
int b_add[maxn];
int change[maxn];
int cnt1 = 0;
int cnt2 = 0;

int main(){
   
	int start_s1,start_s2;
	int N;
	scanf("%d%d%d",&start_s1,&start_s2,&N);
	for(int i=0;i<N;i++){
   
		int add,data,next;
		scanf("%d%d%d",&add,&data,&next);
		next1[add] = next;
		value1[add] = data; 
	}
	
	int s1 = start_s1;
	while(s1!=-1){
   
		a_add[cnt1] = s1;
		a_value[cnt1++] = value1[s1];
		s1 = next1[s1];
	}
	int s2 = start_s2;
	while(s2!=-1){
   
		b_add[cnt2] = s2;
		b_value[cnt2++] = value1[s2];
		s2 = next1[s2];
	}
	if(cnt1>cnt2){
   
		reverse(b_add,b_add+cnt2);
		reverse(b_value,b_value+cnt2);
	}else{
   
		reverse(a_add,a_add+cnt1);
		reverse(a_value,a_value+cnt1);
		for(int i=0;i<cnt1;i++){
   
			change[i] = a_add[i];
		}
		for(int i=0;i<cnt2;i++){
   
			a_add[i] = b_add[i];
		}
		for(int i=0;i<cnt1;i++){
   
			b_add[i] = change[i]; 
		}
		
		for(int i=0;i<cnt1;i++){
   
			change[i] = a_value[i];
		}
		for(int i=0;i<cnt2;i++){
   
			a_value[i] = b_value[i];
		}
		for(int i=0;i<cnt1;i++){
   
			b_value[i] = change[i]; 
		}
		swap(cnt1,cnt2);
	}

	int i = 0;
	int j = 0;
	
	if(cnt1==2*(cnt2)){
   
		while(i<cnt1 && j<cnt2){
   
			if(j!=cnt2-1){
   
				printf("%05d %d %05d\n",a_add[i],a_value[i],a_add[i+1]);
				i++;
				printf("%05d %d %05d\n",a_add[i],a_value[i],b_add[j]);
				i++;
				printf("%05d %d %05d\n",b_add[j],b_value[j],a_add[i]);
				j++;
			}else{
   
				printf("%05d %d %05d\n",a_add[i],a_value[i],a_add[i+1]);
				i++;
				printf("%05d %d %05d\n",a_add[i],a_value[i],b_add[j]);
				i++;
				printf("%05d %d %d\n",b_add[j],b_value[j],-1);
				j++;
			}
		}
	}else{
   
		while(i<cnt1 && j<cnt2){
   
			if(j!=cnt2-1){
   
				printf("%05d %d %05d\n",a_add[i],a_value[i],a_add[i+1]);
				i++;
				printf("%05d %d %05d\n",a_add[i],a_value[i],b_add[j]);
				i++;
				printf("%05d %d %05d\n",b_add[j],b_value[j],a_add[i]);
				j++;
			}else{
   
				printf("%05d %d %05d\n",a_add[i],a_value[i],a_add[i+1]);
				i++;
				printf("%05d %d %05d\n",a_add[i],a_value[i],b_add[j]);
				i++;
				printf("%05d %d %05d\n",b_add[j]</
### 关于 PAT 乙级 1054 题测试点 2 的解决方案 对于 PAT 乙级 1054 题,其核心目标是计算一组数的有效性和平均值。根据已知的信息,在测试点 2 中可能出现的问题主要涉及输入数据中的特殊边界情况。 #### 特殊边界情况分析 在测试点 2 中,可能会存在编号为 `00000` 的人员记录[^2]。这种情况下,默认初始化数组的方式可能导致逻辑判断失误。具体来说: - 如果使用默认的全零初始化方式,则无法区分未录入的数据和实际数值为零的情况。 - 这种混淆可能进一步影响后续有效性验证的结果。 因此,解决此问题的关键在于调整初始状态设置方法,确保能够正确处理这些特殊情况。 #### 修改后的实现策略 以下是针对上述问题提出的改进措施及其对应的 Python 实现代码片段: 为了防止因预设值引发误解, 可考虑采用字典结构来存储每位参与者对应的成绩信息而非固定长度列表. ```python data = {} n = int(input()) for _ in range(n): id_num, score_str = input().split() # 判断分数字符串是否合法 try: value = float(score_str) if not (-1000 <= value <= 1000): raise ValueError('Out of Range') data[id_num] = value except Exception as e: continue valid_scores = list(filter(lambda x : isinstance(x,float), data.values())) avg_score = sum(valid_scores)/len(valid_scores) if valid_scores else 'Undefined' print(f'{len(data)} {avg_score:.1f}') ``` 以上脚本首先创建了一个空字典用于保存有效参赛者的成绩;接着读取每条记录并尝试将其转换成浮点型数字形式存入该字典中(同时执行必要的范围校验);最后统计所有合格得分的数量与算术均值输出即可完成整个流程操作过程描述完毕之后再给出最终结论部分如下所示: 综上所述,通过改用更灵活的数据结构如字典代替原始的一维数组,并严格遵循各项约束条件来进行数据清洗工作便能成功规避掉由特定极端情形所引起的潜在隐患从而顺利通关当前挑战项目[^3].
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值