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

PAT

(Basic Level) Practice - II(1101-1110)

--------------------------------------------------------------------------------
1001-1110(已更新至最新!)

1001-1100

链接:https://pan.baidu.com/s/1Zs7rZn_Z3fyARkwUusviJA
提取码:xkyq

1101-1110

链接:https://pan.baidu.com/s/1hR8bLuuWiDYb2z9XnRxpOQ
提取码:c2yj
--------------------------------------------------------------------------------
更多详见>>
OJ题解系列 目录导航帖
--------------------------------------------------------------------------------

题目传送门

PAT乙级1101-1110
--------------------------------------------------------------------------------

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

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

1104 天长地久 (20 分)数论 + 枚举
1109 擅长C (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],b_value[j],a_add[i]);
				j++;
			}
		}
		while(i<cnt1){
			if(i!=cnt1-1){
				printf("%05d %d %05d\n",a_add[i],a_value[i],a_add[i+1]);
			}else{
				printf("%05d %d %d\n",a_add[i],a_value[i],-1);
			}
			i++;
		}
	}
	
	return 0;
} 

1106 2019数列 (15 分)

算法标签: 模拟
注意点: 初始化数组 a [ 1 ] a [ 2 ] a [ 3 ] a [ 4 ] a[1]a[2]a[3]a[4] a[1]a[2]a[3]a[4],然后依照题目模拟即可

#include<bits/stdc++.h>
using namespace std;
int a[1005]={2,0,1,9};

int main(){
	int n;
	scanf("%d",&n);
	for(int i=4;i<=n;i++){
		int t = a[i-1] + a[i-2] + a[i-3] + a[i-4];
		t = t %10;
		a[i] = t;
	}
	for(int i=0;i<n;i++){
		printf("%d",a[i]);
	}
	
	return 0;
}

1107 老鼠爱大米 (20 分)

算法标签: 排序
注意点: 对于每组老鼠,遍历数据求其最大值,全局的最大值是各组最大中的较大者

#include<bits/stdc++.h>
using namespace std;
int a[15];
int store[105];
int main(){
	int N,M;
	cin >> N >> M;
	
	int max_t = -1;
	for(int i=0;i<N;i++){
		int max_g = -1;
		for(int j=0;j<M;j++){
			int t;
			cin >> t;
			max_g = max(max_g,t);
		}
		store[i] = max_g;
		max_t = max(max_t,max_g);
	}
	for(int i=0;i<N;i++){
		if(i==0){
			printf("%d",store[i]);
		}else{
			printf(" %d",store[i]);
		}
	}
	printf("\n");
	printf("%d\n",max_t);
	return 0;
}

1108 String复读机 (20 分)

算法标签: 字符串 + 哈希
注意点: 哈希表(数组)统计String中每个字符的出现次数,依次按序输出

#include<bits/stdc++.h>
using namespace std;
int a[10];
string out = "String";
int main(){
	string s;
	cin >> s;
	int len = s.size();
	for(int i=0;i<len;i++){
		for(int j=0;j<6;j++){
			if(s[i]==out[j]){
				a[j]++;
			}
		}
	}	
	int cnt = 0;
	for(int i=0;i<6;i++){
		cnt+=a[i];
	}
	while(cnt){
		for(int j=0;j<6;j++){
			if(a[j]){
				printf("%c",out[j]);
				a[j]--;
				cnt--;
			} 
		}
	}
	return 0;
}

1109 擅长C (20 分)

算法标签: 字符串 + 模拟
注意点:
字符串打印类题目,注意首尾不要有多的空格或者换行符。
本题先把单词分离出来,记录有多少个单词,然后再依次每行输出一个单词
采用STL中的string会变得很方便!

#include<bits/stdc++.h>
using namespace std;
string str1[30];
string str2[30];
string str3[30];
string str4[30];
string str5[30];
string str6[30];
string str7[30];

string out1="";
string out2="";
string out3="";
string out4="";
string out5="";
string out6="";
string out7="";

string vocabulary[10005];

int main(){
	for(int i=0;i<26;i++){
		cin >> str1[i];
		cin >> str2[i];
		cin >> str3[i];
		cin >> str4[i];
		cin >> str5[i];
		cin >> str6[i];
		cin >> str7[i];
	}
	getchar();
	string s;
	getline(cin,s);
	int len = s.size();
	int start;
	for(int i=0;i<len;i++){
		if(isupper(s[i])){
			start = i;
			break;
		}
	}
	
	bool f = false;
	int site1 = 0;
	int site2 = 0;
	int cnt = 0;
	for(int i=start;i<len;i++){
		if(!isupper(s[i])&&f){
			f = false;
			site2 = i;
			vocabulary[cnt++] = s.substr(site1,site2-site1);
		}else if(isupper(s[i])&&!f){
			f = true;
			site1 = i;
		}
	}
	if(f){
		site2 = len;
		vocabulary[cnt++] = s.substr(site1,site2-site1);
	}
	
	for(int i=0;i<cnt;i++){
		int l = vocabulary[i].size();
		out1 = "";
		out2 = "";
		out3 = "";
		out4 = "";
		out5 = "";
		out6 = "";
		out7 = "";
	
		for(int j=0;j<l;j++){
			int t = vocabulary[i][j]-'A';
			if(j!=0){
				out1 += " ";
				out2 += " ";
				out3 += " ";
				out4 += " ";
				out5 += " ";
				out6 += " ";
				out7 += " ";
			}
			out1 += str1[t];
			out2 += str2[t];
			out3 += str3[t];
			out4 += str4[t];
			out5 += str5[t];
			out6 += str6[t];
			out7 += str7[t];
		}
			
		if(i!=cnt-1){
			cout << out1 << endl;
			cout << out2 << endl;
			cout << out3 << endl;
			cout << out4 << endl;
			cout << out5 << endl;
			cout << out6 << endl;
			cout << out7 << endl;
			cout << endl;
		}else{
			cout << out1 << endl;
			cout << out2 << endl;
			cout << out3 << endl;
			cout << out4 << endl;
			cout << out5 << endl;
			cout << out6 << endl;
			cout << out7 << endl;
		}
	}
	
	
	
	return 0;
}

1110 区块反转 (25 分)

算法标签: 链表 + 模拟
注意点:
本题采用静态链表的方式存储数据,也可采用1105数组的方式模拟。
每隔K个反转链表,注意链表末尾数据不足,要优先处理!

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int add[maxn];
int value[maxn];
int out_add[maxn];
int out_value[maxn];

struct node{
	int data;
	int next;
};
node n[maxn];
int main(){
	int N;
	int K;
	int start;
	scanf("%d%d%d",&start,&N,&K);	
	for(int i=0;i<N;i++){
		int tmp;
		scanf("%d",&tmp);
		scanf("%d%d",&n[tmp].data,&n[tmp].next);
	}
	int now_add = start;
	int cnt = 0;
	while(now_add!=-1){
		add[cnt] = now_add;
		value[cnt] = n[now_add].data;
		cnt++;
		now_add = n[now_add].next;
	}
	int p = cnt % K;
	int count = 0;
	for(int i=cnt-p;i<cnt;i++){
		out_add[count] = add[i];
		out_value[count] = value[i];
		count++;
	}
	for(int i=cnt-p-K;i>=0;i-=K){
		for(int j=0;j<K;j++){
			out_add[count] = add[i+j];
			out_value[count] = value[i+j];
			count++;
		}
	}
	for(int i=0;i<count;i++){
		if(i!=count-1){
			printf("%05d %d %05d\n",out_add[i],out_value[i],out_add[i+1]);
		}else{
			printf("%05d %d %d\n",out_add[i],out_value[i],-1);
		}
	}
	return 0;
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值