[PAT] 2020年春季赛题目 完整题目 + 完整答案 + 个人总结

13 篇文章 0 订阅
10 篇文章 0 订阅

[PAT] 2020年春季赛题目 完整题目

这次比赛在2020/07/25日举行, 距离比赛截止前5分钟.

100分的人数有: 86人

90分到99分的有: 142人
 

7-1 Prime Day (20分)

The above picture is from Sina Weibo, showing May 23rd, 2019 as a very cool "Prime Day". That is, not only that the corresponding number of the date 20190523 is a prime, but all its sub-strings ended at the last digit 3 are prime numbers.
Now your job is to tell if a given date is a Prime Day.

Input Specification:

Each input file contains one test case. For each case, a date between January 1st, 0001 and December 31st, 9999 is given, in the format yyyymmdd.

Output Specification:

For each given date, output in the decreasing order of the length of the substrings, each occupies a line. In each line, print the string first, followed by a space, then Yes if it is a prime number, or No if not. If this date is a Prime Day, print in the last line All Prime!.

Sample Input 1:

20190523

Sample Output 1:

20190523 Yes
0190523 Yes
190523 Yes
90523 Yes
0523 Yes
523 Yes
23 Yes
3 Yes
All Prime!

Sample Input 2:

20191231

Sample Output 2:

20191231 Yes
0191231 Yes
191231 Yes
91231 No
1231 Yes
231 No
31 Yes
1 No

我的满分答案

#include <bits/stdc++.h>

using namespace std;

bool isPrime(int num){
    if(num==1) return false;                     //关键点1  特判
    for(int i=2; i<=(int)sqrt(1.0*num); i++){    //关键点2  条件<=
        if(num%i==0)
            return false;
    }
    return true;
}
int main()
{
    string str;
    cin>>str;
    int bg = 0, ed = str.size();
    bool flag = true;
    while(bg<ed){
        string tmp = str.substr(bg, ed);
        printf("%s ", tmp.c_str());
        if(isPrime( atoi(tmp.c_str()))){
            printf("Yes\n");
        }else{
            printf("No\n");
            flag = false;
        }
        bg++;
    }
    if(flag){
        printf("All Prime!\n");
    }
    return 0;
}

 

7-2 The Judger (25分)

A game of numbers has the following rules: at the beginning, two distinct positive integers are given by the judge. Then each player in turn must give a number to the judge. The number must be the difference of two numbers that are previously given, and must not be duplicated to any of the existed numbers. The game will run for several rounds. The one who gives a duplicate number or even a wrong number will be kicked out.

Your job is to write a judger program to judge the players' numbers and to determine the final winners.

Input Specification:

Each input file contains one test case. For each case, the first line gives two distinct positive integers to begin with. Both numbers are in [1,10^​5​​ ].

In the second line, two numbers are given: N (2≤N≤10), the number of players, and M (2≤M≤10^3), the number of rounds.

Then N lines follow, each contains M positive integers. The i-th line corresponds to the i-th player (i=1,⋯,N). The game is to start from the 1st player giving his/her 1st number, followed by everybody else giving their 1st numbers in the 1st round; then everyone give their 2nd numbers in the 2nd round, and so on so forth.

Output Specification:

If the i-th player is kicked out in the k-th round, print in a line Round #k: i is out.. The rest of the numbers given by the one who is out of the game will be ignored. If more than one player is out in the same round, print them in increasing order of their indices. When the game is over, print in the last line Winner(s): W1 W2 ... Wn, where W1 ... Wn are the indices of the winners in increasing order. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the beginning or the end of the line. If there is no winner, print No winner. instead.

Sample Input 1:

101 42
4 5
59 34 67 9 7
17 9 8 50 7
25 92 43 26 37
76 51 1 41 40

Sample Output 1:

Round #4: 1 is out.
Round #5: 3 is out.
Winner(s): 2 4

Sample Input 2:

42 101
4 5
59 34 67 9 7
17 9 18 50 49
25 92 58 1 39
102 32 2 6 41

Sample Output 2:

Round #1: 4 is out.
Round #3: 2 is out.
Round #4: 1 is out.
Round #5: 3 is out.
No winner.

我的答案:

没读懂题, 没读懂题, 没读懂题....

7-3 Safari Park (25分)

A safari park(野生动物园)has K species of animals, and is divided into N regions. The managers hope to spread the animals to all the regions, but not the same animals in the two neighboring regions. Of course, they also realize that this is an NP complete problem, you are not expected to solve it. Instead, they have designed several distribution plans. Your job is to write a program to help them tell if a plan is feasible.

Input Specification:

Each input file contains one test case. For each case, the first line gives 3 integers: N (0<N≤500), the number of regions; R (≥0), the number of neighboring relations, and K (0<K≤N), the number of species of animals. The regions and the species are both indexed from 1 to N.

Then R lines follow, each gives the indices of a pair of neighboring regions, separated by a space.

Finally there is a positive M (≤20) followed by M lines of distribution plans. Each plan gives N indices of species in a line (the i-th index is the animal in the i-th rigion), separated by spaces. It is guaranteed that any pair of neighboring regions must be different, and there is no duplicated neighboring relations.

Output Specification:

For each plan, print in a line Yes if no animals in the two neighboring regions are the same, or No otherwise. However, if the number of species given in a plan is not K, you must print Error: Too many species. or Error: Too few species. according to the case.

Sample Input:

6 8 3
2 1
1 3
4 6
2 5
2 4
5 4
5 6
3 6
5
1 2 3 3 1 2
1 2 3 4 5 6
4 5 6 6 4 5
2 3 4 2 3 4
2 2 2 2 2 2

Sample Output:

Yes
Error: Too many species.
Yes
No
Error: Too few species.

我的没全过答案:

对题意的理解有偏差, 没有想到这是一个考图的题目...

#include <bits/stdc++.h>

using namespace std;
int uni(int n, int order[], int k){
    int spe = 0;
    map<int, bool> imap;
    for(int i=1; i<=n; i++){
        if(imap.find(order[i])==imap.end()){
            spe++;
            imap[order[i]] = true;
        }
    }
    if(spe == k) return 0;
    else if(spe < k) return -1;
    else if(spe > k) return 1;
}

int main()
{
    int n, r, k;
    scanf("%d %d %d", &n, &r, &k);
    pair<int, int> p;
    map<pair<int, int>, bool> pmap;
    for(int i=1; i<=r; i++){
        p.first = i;
        p.second = i;
        pmap[p] = true;
    }
    for(int i=1; i<=r; i++){
        int aa, bb;
        scanf("%d %d", &aa, &bb);
        p.first = aa; p.second = bb;
        pmap[p] = true;
        p.second = aa; p.first = bb;
        pmap[p] = true;
    }
    int order[n+1];
    int m;
    scanf("%d", &m);
    for(int j=1; j<=m; j++){
        for(int i=1; i<=n; i++){
            scanf("%d", &order[i]);
        }
        if( uni(n, order, k)==1 ){
            printf("Error: Too many species.\n");
        }else if( uni(n, order, k) == -1){
            printf("Error: Too few species.\n");
        }else{
            bool flag = true;
            for(int u=1; u<=n-1; u++){
                p.first = order[u];
                p.second = order[u+1];
                if(pmap.find(p)==pmap.end()){
                    printf("No\n");
                    flag = false;
                    break;
                }
            }
            if(flag) printf("Yes\n");
        }
    }

    return 0;
}

7-4 Replacement Selection (30分)

When the input is much too large to fit into memory, we have to do external sorting instead of internal sorting. One of the key steps in external sorting is to generate sets of sorted records (also called runs) with limited internal memory. The simplest method is to read as many records as possible into the memory, and sort them internally, then write the resulting run back to some tape. The size of each run is the same as the capacity of the internal memory.

Replacement Selection sorting algorithm was described in 1965 by Donald Knuth. Notice that as soon as the first record is written to an output tape, the memory it used becomes available for another record. Assume that we are sorting in ascending order, if the next record is not smaller than the record we have just output, then it can be included in the run.

For example, suppose that we have a set of input { 81, 94, 11, 96, 12, 99, 35 }, and our memory can sort 3 records only. By the simplest method we will obtain three runs: { 11, 81, 94 }, { 12, 96, 99 } and { 35 }. According to the replacement selection algorithm, we would read and sort the first 3 records { 81, 94, 11 } and output 11 as the smallest one. Then one space is available so 96 is read in and will join the first run since it is larger than 11. Now we have { 81, 94, 96 }. After 81 is out, 12 comes in but it must belong to the next run since it is smaller than 81. Hence we have { 94, 96, 12 } where 12 will stay since it belongs to the next run. When 94 is out and 99 is in, since 99 is larger than 94, it must belong to the first run. Eventually we will obtain two runs: the first one contains { 11, 81, 94, 96, 99 } and the second one contains { 12, 35 }.

Your job is to implement this replacement selection algorithm.

Input Specification:

Each input file contains several test cases. The first line gives two positive integers N (≤10
​5
​​ ) and M (<N/2), which are the total number of records to be sorted, and the capacity of the internal memory. Then N numbers are given in the next line, all in the range of int. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in each line a run (in ascending order) generated by the replacement selection algorithm. All the numbers in a line must be separated by exactly 1 space, and there must be no extra space at the beginning or the end of the line.

Sample Input

13 3
81 94 11 96 12 99 17 35 28 58 41 75 15

Sample Output:

11 81 94 96 99
12 17 28 35 41 58 75
15

我的没全过答案:

两个测试点超时

#include <bits/stdc++.h>

using namespace std;

void initmem(int n, int m, int num[], int mem[], int vis[], int &cntn){
    int cntmem = 0;
    for(int i = 0; i < n && cntmem < m; i++){
        if(vis[i] == false){
            mem[cntmem++] = num[i];
            vis[i] = true;
            cntn--;
        }
    }
}
int judge(int n, int vis[]){
    int temp = 0;
    for(int i=0; i<n; i++){
        if(vis[i]==false)
            temp++;
    }
    return temp;
}
int main()
{
    int n, m;
    scanf("%d %d", &n, &m);
    int cntn = n;
    int mem[m];
    int num[n];
    int vis[n] = {false};
    int output[n];
    int cntout = 0;
    for(int i=0; i<n; i++){
        scanf("%d", &num[i]);
    }
    int run = 0;
    int flag = 0;
    while(cntn = judge(n, vis)){
        flag = cntn;
        cntout = 0;
        initmem(n, m, num, mem, vis, cntn);
        sort(mem, mem+m, less<int>());
        output[cntout++] = mem[0]; cntn--;
        int i = 0;
        while(i < n){
            if(vis[i] == false){
                if(num[i] > output[cntout-1]){
                    mem[0] = num[i];
                    vis[i] = true;
                    sort(mem, mem+m, less<int>());
                    output[cntout++] = mem[0]; cntn--;
                }
                i++;
            }else{
                i++;
            }
        }
        if(flag>m){
            flag = m;
        }
        for(int j = 1; j < flag; j++){
            output[cntout++] = mem[j];
        }
        for(int j = 0; j < cntout; j++){
            printf("%d", output[j]);
            if(j!=cntout-1) printf(" ");
            else printf("\n");
        }
    }
    return 0;
}

以上题目的完整正确答案:

此章节代码转自CSDN博主「如椽大笔_S686」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ZiYuTongXue/article/details/107582557

为防止作者删帖和便于查看, 已将大佬代码汇总于此.

7-1

#include<iostream>
#include<vector>
#include<string>
#include<math.h>
using namespace std;
bool isprime(int x) {
	if (x <= 1)return false;
	for (int i = 2; i <= sqrt(x); i++) {
		if (x%i == 0)return false;
	}
	return true;
}
int main() {
	int num = 0;
	string s;
	cin >> s;
	while (s.length()) {
		printf("%s ", s.c_str());
		if (isprime(stoi(s)))printf("Yes\n");
		else {
			printf("No\n");
			num++;
		}
		s.erase(s.begin());
	}
	if (num == 0)printf("All Prime!\n");
	return 0;
}

7-2

#include<iostream>
#include<vector>
#include<math.h>
bool possible[1000000];
bool val[1000000];
bool flag[11];
using namespace std;
vector<vector<int> >V;
int main() {
	int N, M, v1, v2, v;
	scanf("%d%d%d%d", &v1, &v2,&N,&M);
	possible[abs(v1 - v2)] = true;
	val[v1] = true;
	val[v2] = true;
	V.resize(N + 1);
	for (int i = 1; i <= N; i++) {
		V[i].resize(M + 1);
		for (int j = 1; j <= M; j++) {
			scanf("%d", &V[i][j]);
		}
	}
	vector<int>ex;
	ex.push_back(v1);
	ex.push_back(v2);
	for (int i = 1; i <= M; i++) {
		for (int j = 1; j <= N; j++) {
			if (flag[j] == true)continue;
			int round = i, player = j, num = V[j][i];
			if (val[num] || !possible[num]) {
				flag[player] = true;//跳过
				printf("Round #%d: %d is out.\n", round, player);
			}
			else {
				val[num] = true;
				for (int i = 0; i < ex.size(); i++) {
					possible[abs(num - ex[i])] = true;
				}
				ex.push_back(num);
			}
		}
	}
	vector<int>tmp;
	for (int i = 1; i <= N; i++) {
		if (!flag[i])tmp.push_back(i);
	}
	if (tmp.size() > 0) {
		printf("Winner(s):");
		for (int i = 0; i < tmp.size(); i++)printf(" %d", tmp[i]);
	}
	else printf("No winner.");
	printf("\n");
	return 0;
}

7-3

#include<vector>
#include<iostream>
#include<map>
using namespace std;
const int inf = 10000000;
int G[510][510];
vector<int>V[510];
int N, M, K;
int main() {
	int v1, v2, num, val;
	scanf("%d%d%d", &N, &M, &K);
	for (int i = 0; i < M; i++) {
		scanf("%d%d", &v1, &v2);
		V[v1].push_back(v2);
		V[v2].push_back(v1);
		G[v1][v2] = G[v2][v1] = 1;
	}
	scanf("%d", &num);
	for (int i = 0; i < num; i++) {
		map<int, int>Ma;
		vector<int>tmp;
		tmp.push_back(0);
		for (int j = 0; j < N; j++) {
			scanf("%d", &val);
			tmp.push_back(val);
			Ma[val] = 1;
		}
		if (Ma.size() != K) {
			if (Ma.size() > K)printf("Error: Too many species.\n");
			else printf("Error: Too few species.\n");
		}
		else {
			bool flag = true;
			for (int i = 1; i <= N; i++) {
				for (int j = 0; j < V[i].size(); j++) {
					if (tmp[i] == tmp[V[i][j]]) {
						flag = false;
						break;
					}
				}
				if (flag == false)break;
			}
			if (flag)printf("Yes\n");
			else printf("No\n");
		}
	}
	return 0;
}

7-4

#include<iostream>
#include<vector>
#include<map>
using namespace std;
int main() {
	int N, M, val;
	scanf("%d%d", &N, &M);
	map<int, int>Ma, Mb;
	for (int i = 0; i < M; i++) {
		scanf("%d", &val);
		Ma[val]++;
	}
	vector<int>tmp;
	vector<vector<int>>ans;
	for (int i = M; i < N; i++) {
		scanf("%d", &val);
		int head = Ma.begin()->first;
		if(Ma.begin()->second==1)Ma.erase(Ma.begin());
		else Ma[Ma.begin()->first]--;
		tmp.push_back(head);
		if (val >= head)Ma[val]++;
		else Mb[val]++;
		if (Ma.size() == 0) {
			Ma = Mb;
			Mb.clear();
			ans.push_back(tmp);
			tmp.clear();
		}
		if (i == N - 1) {
			while (Ma.size()) {
				tmp.push_back(Ma.begin()->first);
				if(Ma.begin()->second==1) Ma.erase(Ma.begin());
				else Ma[Ma.begin()->first]--;
			}
			if (tmp.size() > 0)ans.push_back(tmp);
			tmp.clear();
			while (Mb.size()) {
				tmp.push_back(Mb.begin()->first);
				if (Mb.begin()->second == 1) Mb.erase(Mb.begin());
				else Mb[Mb.begin()->first]--;
			}
			ans.push_back(tmp);
		}
	}
	for (int i = 0; i < ans.size(); i++) {
		for (int j = 0; j < ans[i].size(); j++) {
			if (j == 0)printf("%d", ans[i][j]);
			else printf(" %d", ans[i][j]);
			if (j == ans[i].size() - 1)printf("\n");
		}
	}
	return 0;
}

总结

题目不难, 但是我也不知道会考什么, 只是照着算法笔记书上的代码复习, 至少所有的代码我都做成了ppt和anki卡片,

可以说大部分算法都能背过了, 但是没想到还是栽了. 62分勉强及格的成绩排名743.

 

7-1我大概用了10-15分钟就写完了, 一气呵成, 没有错误和调试. 当时做完看了一眼提交列表, 排名第二, 第一第三题就已经做出来了, 我就觉得第三题可能比较简单, 于是直接做的第三题, 第三题我做了大概有约1小时, 读题花了很长时间, 又用程序去碰运气, 做完第三题的部分测试点, 拿到了20+分, 此时还有1个小时. 然后去看的第二题, 第二题我读了n遍, 花了有20+mins始终不理解题意, 然后去做了第四题, 第四题做了约1小时, 拿到了20+分, 此时还有30+mins, 抄下样例数据, 琢磨了琢磨, 发现看不懂, 炸裂啊, difference是什么啊? 怎么回事啊.... 然后就到了交卷. 

 

事后总结一下就是我栽在了 英语阅读->正确题意->归纳模型/算法 的过程

如果你有幸读到这里, 请一定培养一下你的英语阅读能力.

 

说到7-2我没懂difference的含义.

但是, 因为疫情原因, 首次线上考试, 之前为了测试大家的环境举办过一次模拟考试, 模拟考试内容出自PAT甲级原题. 其中模拟考试的第一题是实现分数的加减乘除, 题目是A1088/B1034(为A1088翻译), 题中曾这样说道:

For two rational numbers, your task is to implement the basic arithmetics, that is, to calculate their sum, difference, product and quotient.

加减乘除有没有! 加减乘除有没有! 加减乘除有没有!

我也是事后诸葛亮, 考完试去google翻译翻译看到difference是减的意思, 恍然想起来三天前的模拟考有这个词.

所以说没必要找陈越姥姥诉苦水了.

要么你没参加模拟测试, 要么是你参加了你没记住, 都是自己的问题

 

7-3 我也没有准确的理解题意.

只是根据样例的特点, 写出了一个程序能过样例. 更是没有将这道题的模型归结到图上面去. 虽然之前背了很多关于图的模板

 

7-4 是我唯一看懂的一道题目

中间也调试了一段时间, 也是在有限的时间里拿到了20+的分数, 有两个测试点超时.

 

另外还有一个重要的事情是:

备考期间多看看网上别人的备考攻略, 看看历年真题都考了什么, 有些考点其实不需要花太大精力去扣, 去背.

理解算法, 理解这些数据结构, 能把题目有效的转换为你所学过的模型/算法/数据结构才是最重要的.

 

另外, 希望9月的PAT考试还能进行.

实在不甘心.

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值