2021春PAT甲级满分题解

orz:第一题素数筛+暴力 注意处理n==1的情况,第二题区间贪心,算法笔记上有原题,第三题水题,注意是逐个插入建树,所以是向上调整,第四题忘了floyd怎么写的,用的n遍dijkstra

7-1 Arithmetic Progression of Primes (20 分)

In mathematics, an arithmetic progression (AP,等差数列) is a sequence of numbers such that the difference between the consecutive terms is constant. In 2004, Terence Tao (陶哲轩) and Ben Green proved that for any positive n, there exists at least one arithmetic progression consists of n consecutive prime numbers. For example, { 7,37,67,97,127,157 } is one solution for n=6. Now it is your job to find a maximum solution for a given n within a given range.

Input Specification:

Each input file contains one test case, which gives two positive integers in a line: n (≤10), the number of consecutive prime terms in an arithmetic progression, and MAXP (2≤MAXP<10​5), the upper bound of the largest prime in the solution.
Output Specification:

For each test case, if there exists a solution, print in ascending order the prime numbers in a line. If the solution is not unique, output the one with the maximum common difference. If there is still a tie, print the one with the maximum first number. If there is no solution bounded by MAXP, output the largest prime in the given range instead.

All the numbers in a line must be separated by a space, and there must be no extra space at the beginning or the end of the line.

Sample Input:

5 1000

Sample Output:

23 263 503 743 983

Sample Input 2:

10 200

Sample Output 2:

199

#include<iostream>
using namespace std;
const int maxn=100000;
int n,Maxp;
bool Prime[maxn];
int num[maxn],pNum=0;
void init(){
	fill(Prime,Prime+maxn,false);
	Prime[1]=true;
	Prime[0]=true;
	for(int i=2;i<=Maxp;i++){
		if(Prime[i]==false){
			num[pNum++]=i;
			for(int j=i+i;j<=Maxp;j+=i){
				Prime[j]=true;
			}
		}
	}
}
int main(){
	bool flag=false;
	int ans;
	int Max=-1;
	scanf("%d %d",&n,&Maxp);
	init();

	for(int i=pNum-1;i>=0;i--){
		for(int j=i-1;j>=0;j--){
			bool flag1=true;
			int temp=num[i]-num[j];
			if(temp<Max)continue;
			for(int t=0;t<n;t++){
				if(num[i]-temp*(t)<0){
					flag1=false;break;
				}
				if(Prime[num[i]-temp*(t)]==false) ;
				else {
					flag1=false;
					break;
				}
			}
			if(flag1){
				if(temp>Max){
					flag=true;
					Max=temp;
					ans=i;
				}
			}
		}
	}
	if(!flag) {
		if(Maxp!=2)printf("%d",num[pNum-1]);
		else printf("2");
		return 0;
	}
	for(int i=n-1;i>=0;i--){
		if(i!=n-1) printf(" ");
		printf("%d",num[ans]-i*Max);
	}
	return 0;
} 

7-2 Lab Access Scheduling (25 分)

Nowadays, we have to keep a safe social distance to stop the spread of virus due to the COVID-19 outbreak. Consequently, the access to a national lab is highly restricted. Everyone has to submit a request for lab use in advance and is only allowed to enter after the request has been approved. Now given all the personal requests for the next day, you are supposed to make a feasible plan with the maximum possible number of requests approved. It is required that at most one person can stay in the lab at any particular time.

Input Specification:

Each input file contains one test case. Each case starts with a positive integer N (≤2×103), the number of lab access requests. Then N lines follow, each gives a request in the format:

hh:mm:ss hh:mm:ss

where hh:mm:ss represents the time point in a day by hour:minute:second, with the earliest time being 00:00:00 and the latest 23:59:59. For each request, the two time points are the requested entrance and exit time, respectively. It is guaranteed that the exit time is after the entrance time.

Note that all times will be within a single day. Times are recorded using a 24-hour clock.
**

Output Specification:

**

The output is supposed to give the total number of requests approved in your plan.

Sample Input:

7
18:00:01 23:07:01
04:09:59 11:30:08
11:35:50 13:00:00
23:45:00 23:55:50
13:00:00 17:11:22
06:30:50 11:42:01
17:30:00 23:50:00

Sample Output:

5

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct node{
	int hh1,mm1,ss1,hh2,mm2,ss2;
	int time1,time2;
};
int gettime1(node temp){
	return temp.hh1*3600+temp.mm1*60+temp.ss1;
}
int gettime2(node temp){
	return temp.hh2*3600+temp.mm2*60+temp.ss2;
}
bool cmp(node a,node b){
	if(a.time2!=b.time2) return a.time2<b.time2;
	else return a.time1>b.time1;
}
int main(){
	int n;
	scanf("%d",&n);
	vector<node> peo(n);
	for(int i=0;i<n;i++){
		scanf("%d:%d:%d %d:%d:%d",&peo[i].hh1,&peo[i].mm1,&peo[i].ss1,&peo[i].hh2,&peo[i].mm2,&peo[i].ss2);
		peo[i].time1=gettime1(peo[i]);
		peo[i].time2=gettime2(peo[i]);
	}
	sort(peo.begin(),peo.end(),cmp);
	int lastime=peo[0].time2;
	int ans=1;
	for(int i=1;i<n;i++){
		if(peo[i].time1>=lastime){
			//printf("%d\n",i);
			lastime=peo[i].time2;
			ans++;
		}
	}
	printf("%d",ans);
	return 0;
}

7-3 Structure of Max-Heap (25 分)

In computer science, a max-heap is a specialized tree-based data structure that satisfies the heap property: if P is a parent node of C, then the key (the value) of P is greater than or equal to the key of C. A common implementation of a heap is the binary heap, in which the tree is a complete binary tree.

Your job is to first insert a given sequence of integers into an initially empty max-heap, then to judge if a given description of the resulting heap structure is correct or not. There are 5 different kinds of description statements:

x is the root
x and y are siblings
x is the parent of y
x is the left child of y
x is the right child of y

Input Specification:

Each input file contains one test case. For each case, the first line gives 2 positive integers: N (≤1,000), the number of keys to be inserted, and M (≤20), the number of statements to be judged. Then the next line contains N distinct integer keys in [−104,104] which are supposed to be inserted into an initially empty max-heap. Finally there are M lines of statements, each occupies a line.

Output Specification:

For each statement, print 1 if it is true, or 0 if not. All the answers must be print in one line, without any space.

Sample Input:

5 6
23 46 26 35 88
35 is the root
46 and 26 are siblings
88 is the parent of 46
35 is the left child of 26
35 is the right child of 46
-1 is the root

Sample Output:

011010

#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
using namespace std;
vector<int> num;
int n,m;
unordered_map<int,int> pos;
void upAdjust(int low,int high){
	int j=high,i=j/2;
	while(i>=low){
		if(num[j]>num[i]){
			swap(num[j],num[i]);
			j=i;
			i/=2;
		}
		else break;
	}
}
void dfs(int root){
	pos[num[root]]=root;
	if(root*2<=n){
		dfs(root*2);
	}
	if(root*2+1<=n){
		dfs(root*2+1);
	}
}
int main(){
	scanf("%d %d",&n,&m);
	num.resize(n+1);
	for(int i=1;i<=n;i++){
		scanf("%d",&num[i]);
	}
	for(int i=2;i<=n;i++){
		upAdjust(1,i);
	}
	dfs(1);
	for(int i=1;i<=n;i++){
		//printf("%d %d\n",num[i],pos[num[i]]);
	}
	string ans;
	getchar();
	for(int i=0;i<m;i++){
		bool flag=true;
		string str;
		getline(cin,str);
		if(str.find("left")!=string::npos){
			int sum=stoi(str.substr(0,str.find(" ")));
			str=str.substr(str.find("of "));
			int father=stoi(str.substr(3));
			if(pos.find(sum)==pos.end()||pos.find(father)==pos.end()||pos[sum]!=pos[father]*2)flag=false;
		}
		else if(str.find("right")!=string::npos){
			int sum=stoi(str.substr(0,str.find(" ")));
			str=str.substr(str.find("of "));
			int father=stoi(str.substr(3));
			if(pos.find(sum)==pos.end()||pos.find(father)==pos.end()||pos[sum]!=pos[father]*2+1)flag=false;
		}
		else if(str.find("root")!=string::npos){
			int temp=stoi(str.substr(0,str.find(" ")));
			if(pos.find(temp)==pos.end()||pos[temp]!=1) flag=false;
		}
		else if(str.find("parent")!=string::npos){
			int father=stoi(str.substr(0,str.find(" ")));
			str=str.substr(str.find("of "));
			int sum=stoi(str.substr(3));
			if(pos.find(sum)==pos.end()||pos.find(father)==pos.end()||pos[sum]/2!=pos[father])flag=false;
		}
		else {
			int temp=stoi(str.substr(0,str.find(" ")));
			
			str=str.substr(str.find("and "));
			int temp2=stoi(str.substr(4));
			//printf("%d %d\n",temp,temp2);
			if(pos.find(temp)==pos.end()||pos.find(temp2)==pos.end()||pos[temp]/2!=pos[temp2]/2)flag=false;
		}
		if(flag)ans+="1";
		else ans+="0";
	}
	printf("%s",ans.c_str());
	return 0;
}

7-4 Recycling of Shared Bicycles (30 分)

There are many spots for parking the shared bicycles in Hangzhou. When some of the bicycles are broken, the management center will receive a message for sending a truck to collect them. Now given the map of city, you are supposed to program the collecting route for the truck. The strategy is a simple greedy method: the truck will always move to the nearest spot to collect the broken bicycles. If there are more than one nearest spot, take the one with the smallest index.

Input Specification:

Each input file contains one test case. For each case, the first line contains two positive integers: N (≤ 200), the number of spots (hence the spots are numbered from 1 to N, and the management center is always numbered 0), and M, the number of streets connecting those spots. Then M lines follow, describing the streets in the format:

S1 S2 Dist

where S1 and S2 are the spots at the two ends of a street, and Dist is the distance between them, which is a positive integer no more than 1000. It is guaranteed that each street is given once and S1 is never the same as S2.

Output Specification:

For each case, first print in a line the sequence of spots in the visiting order, starting from 0. If it is impossible to collect all the broken bicycles, output in the second line those spots that cannot be visited, in ascending order of their indices. Or if the job can be done perfectly, print in the second line the total moving distance of the truck.

All the numbers in a line must be separated by 1 space, and there must be no extra space at the beginning or the end of the line.

Sample Input:

7 10
0 2 1
0 4 5
0 7 3
0 6 4
0 5 5
1 2 2
1 7 2
2 3 4
3 4 2
6 7 9

Sample Output:

0 2 1 7 6 3 4 5
33

Sample Input 2:

7 8
0 2 1
0 4 5
0 7 3
1 2 2
1 7 2
2 3 4
3 4 2
6 5 1

Sample Output 2:

0 2 1 7 3 4
5 6

#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
#include<algorithm>
using namespace std;
const int maxn=210;
const int INF=1000000000;
int G[maxn][maxn];
int d[maxn];
bool vis[maxn],Hash[maxn];
int n,m;
int sum=0;
vector<int> ans;
void Dijkstra(int s){
	fill(d,d+maxn,INF);
	fill(vis,vis+maxn,false);
	d[s]=0;
	for(int i=0;i<=n;i++){
		int u=-1,Min=INF;
		for(int j=0;j<=n;j++){
			if(d[j]<Min&&vis[j]==false){
				u=j;
				Min=d[j];
			}
		}
		if(u==-1) break;
		vis[u]=true;
		for(int v=0;v<=n;v++){
			if(G[u][v]!=INF&&vis[v]==false){
				if(d[u]+G[u][v]<d[v]){
					d[v]=d[u]+G[u][v];
				}
			}
		}
	}
}
void dfs(int s){
	if(ans.size()==n+1){
		return;
	}
	int u=-1,Max=INF;
	Dijkstra(s);
	for(int i=0;i<=n;i++){
		if(d[i]<Max&&Hash[i]==false){
			u=i;
			Max=d[i];
		}
	}
	if(u==-1) return;
	Hash[u]=true;
	ans.push_back(u);
	sum+=d[u];
	dfs(u);
}
int main(){
	fill(Hash,Hash+maxn,false);
	fill(G[0],G[0]+maxn*maxn,INF);
	int a,b,temp;
	scanf("%d %d",&n,&m);
	for(int i=0;i<m;i++){
		scanf("%d %d %d",&a,&b,&temp);
		G[a][b]=G[b][a]=temp;
	}
	dfs(0);
	for(int i=0;i<ans.size();i++){
		if(i!=0) printf(" ");
		printf("%d",ans[i]);
	}
	printf("\n");
	if(ans.size()!=n+1){
		bool flag1=false;
		for(int i=0;i<=n;i++){
			if(Hash[i]==false){
				if(flag1==false)flag1=true;
				else printf(" ");
				printf("%d",i);
			}
		}
	}
	else {
		printf("%d",sum);
	}
	return 0;
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值