2021pat春季93分总结

一、 Arithmetic Progression of Primes (20 分)

分析:输入n和maxp,找出maxp范围内n个间隔最大的素数。上来就是挺麻烦的一道题,想了好多种方法,最后还是暴力解体,将所有素数放到了一个数组里面,从后往前遍历,间隔逐渐减小。套了三层循环,所以有一测试点超时了,不知道怎么改,扣了三分。

#include<bits/stdc++.h>
using namespace std;
set<int> s;
vector<int> num(100050, 0), v;
bool prime(int x){
	num[2] = 1;
	s.insert(2);
	for(int i=2; i<=x; i++){
		int flag = 0;
		for(int j=2; j<=sqrt(i)+1; j++){
			if(i % j == 0){
				flag = 1;
			}
		}
		if(flag == 0){
			num[i] = 1;
			s.insert(i);
		}
	}
	for(auto it=s.begin(); it!=s.end(); it++){
		v.push_back(*it);
	}
}
int main(){
	int n, maxp;
	scanf("%d %d", &n, &maxp);
	prime(maxp);
	int cnt = -1;
	int dis = -1;
	if(n != 1){
		dis = maxp/(n-1);
		while(1){
			int flag1 = 0;
			if(dis == 0){
				break;
			}
			for(int i=v.size()-1; i>=0; i--){
				int flag = 0;
				for(int j=0; j<n; j++){
					if(find(v.begin(), v.end(), v[i] - dis*j) == v.end()){
						flag = 1;
					}
				}
				if(flag == 0){
					cnt = v[i];
					flag1 = 1;
					break;
				}
			}
			if(flag1 == 1){
				break;
			}
			dis--;
		}
	}
	if(cnt != -1){
		for(int i=n-1; i>=0; i--){
			if(i != n-1) printf(" ");
			printf("%d", cnt - dis*i);
		}
	}else{
		int maxi = -1;
		for(auto it=s.begin(); it!=s.end(); it++){
			maxi = max(*it, maxi);
		}
		printf("%d", maxi);
	}
		
	return 0;
} 

二、Lab Access Scheduling (25 分)

分析:输入n,n行开始时间与结束时间,找出在一天内最多能安排几个节目。唯一的一道水题,使用贪心算法,按结束时间来排序,每次取起始时间比上一个结束时间大的。

#include<bits/stdc++.h>
using namespace std;
struct requ{
	int start, end;
};
requ r[2050];
bool cmp(requ a, requ b){
	return a.end < b.end;
}
int main(){
	int n, sh, sm, ss, eh, em, es;
	cin >> n;
	for(int i=0; i<n; i++){
		scanf("%d:%d:%d", &sh, &sm, &ss);
		scanf("%d:%d:%d", &eh, &em, &es);
		r[i].start = sh*3600 + sm*60 + ss;
		r[i].end = eh*3600 + em*60 + es;
	}
	sort(r, r+n, cmp);
	int mstart = r[0].start, mend = r[0].end, sum = 1;
	for(int i=1; i<n; i++){
		if(r[i].start >= mend){
			sum++;
			mend = r[i].end;
		}
	}
	cout << sum;
	return 0;
}

三、Structure of Max-Heap (25 分)

分析:输入n个数,将其构成大根堆,再输入m行,每行有一个判断句,正确就输出1,否则0。这道题的输入是真的麻烦,题目倒是不难,无非就是拿到数后去判断是否正确。但有一个测试点错了,不知道错在哪,扣了4分。

#include<bits/stdc++.h>
using namespace std;
int heap[1050];
int len = 1;
void Insert(int k){
	heap[len++] = k;
	int cnt = len-1;
	while(cnt != 1 && cnt != 0){
		if(heap[cnt] > heap[cnt/2]){
			int temp = heap[cnt];
			heap[cnt] = heap[cnt/2];
			heap[cnt/2] = temp;
			cnt = cnt/2;
		}else{
			break;
		}
	}	
}
int main(){
	int n, m, k;
	cin >> n >> m;
	for(int i=0; i<n; i++){
		cin >> k;
		Insert(k);
	}
	string my = "";
	for(int i=0; i<m; i++){
		int x, xi = 0;
		string s;
		scanf("%d", &x);
		getline(cin, s);
		if(s[1] == 'i'){
			if(s[9] == 'a'){//parent
				string res = "";
				for(int i=5; i<s.size(); i++){
					if(isdigit(s[i])){
						res += s[i];
					}
				}
				int y = stoi(res);
				int yi = 0;
				for(int j=1; j<len; j++){
					if(x == heap[j]){
						xi = j;
					}
					if(y == heap[j]){
						yi = j;
					}
				}
				if(xi == yi/2 && xi != 0 && yi != 0){
					my += '1';
				}else{
					my += '0';
				}
			}
			if(s[9] == 'e'){//left
				string res = "";
				for(int i=5; i<s.size(); i++){
					if(isdigit(s[i])){
						res += s[i];
					}
				}
				int y = stoi(res);
				int yi = 0;
				for(int j=1; j<len; j++){
					if(x == heap[j]){
						xi = j;
					}
					if(y == heap[j]){
						yi = j;
					}
				}
				if(yi*2 == xi && xi != 0 && yi != 0){
					my += '1';
				}else{
					my += '0';
				}
			}
			if(s[9] == 'i'){//right
				string res = "";
				for(int i=5; i<s.size(); i++){
					if(isdigit(s[i])){
						res += s[i];
					}
				}
				int y = stoi(res);
				int yi = 0;
				for(int j=1; j<len; j++){
					if(x == heap[j]){
						xi = j;
					}
					if(y == heap[j]){
						yi = j;
					}
				}
				if(yi*2+1 == xi && xi != 0 && yi != 0){
					my += '1';
				}else{
					my += '0';
				}
			}
			if(s[9] == 'o'){//root
				if(heap[1] == x){
					my += '1';
				}else{
					my += '0';
				}
			}
		}else{
			string res = "";
			for(int i=5; i<s.size(); i++){
				if(isdigit(s[i])){
					res += s[i];
				}
			}
			int y = stoi(res);
			int yi = 0;
			for(int j=1; j<len; j++){
				if(x == heap[j]){
					xi = j;
				}
				if(y == heap[j]){
					yi = j;
				}
			}
			if(yi/2 == xi/2 && xi != 0 && yi != 0){
				my += '1';
			}else{
				my += '0';
			}
		}
	}
	cout << my << endl;
	return 0;
}

四、Recycling of Shared Bicycles (30 分)

分析:有n个点,输入m行路径,寻找最短的一条路能从0开始尽量所有点。乱搞出来的,一开始我以为和老题目一样,求一个点的最短路径,其实不然,它没有表明末尾的点,那也就是说每走一步都要去找离自己最近的点,然后正在走的点变成为这个点。我建了个dis的二维数组,将每个点与各个点的最短路径都保存了,然后再一次使用dijkstra算法,每次改变点的位置,找出最短的路径。

#include<bits/stdc++.h>
using namespace std;
const int inf = 99999999;
int dis[220][220], e[220][220];
bool visit[220];
vector<int> pre[220], path, res, my;
int maxr = -1;
int main(){
	fill(dis[0], dis[0]+220*220, inf);
	fill(e[0], e[0]+220*220, inf);
	int n, m, a1, a2, d;
	cin >> n >> m;
	for(int i=0; i<m; i++){
		cin >> a1 >> a2 >> d;
		e[a1][a2] = d;
		e[a2][a1] = d;
	}
	int now = 0;
	for(int k=0; k<=n; k++){
		dis[k][k] = 0;
		fill(visit, visit+220, false);
		for(int i=0; i<=n; i++){
			int u = -1, mini = inf;
			for(int j=0; j<=n; j++){
				if(visit[j] == false && mini > dis[k][j]){
					u = j;
					mini = dis[k][j];
				}
			}
			if(u == -1) break;
			visit[u] = true;
			for(int v=0; v<=n; v++){
				if(visit[v] == false && e[u][v] != inf){
					if(dis[k][u] + e[u][v] < dis[k][v]){
						dis[k][v] = dis[k][u] + e[u][v];
					}
				}
			}
		}
	}
	fill(visit, visit+220, false);
	int nnow = 0;
	visit[0] = true;
	my.push_back(0);
	for(int i=0; i<=n; i++){
		int mini = inf, u = -1;
		for(int k=0; k<=n; k++){
			if(nnow != k && visit[k] == false && dis[nnow][k] < mini){
				u = k;
				mini = dis[nnow][k];
			}
		}
		if(u == -1){
			break;
		} 
		visit[u] = true;
		my.push_back(u);
		nnow = u;
	}
	for(int i=0; i<my.size(); i++){
		if(i != 0) cout << " ";
		cout << my[i];
	}
	cout << endl;
	int flag = 0;
	for(int i=0; i<=n; i++){
		if(dis[0][i] == inf){
			if(flag != 0)cout << " ";
			cout << i;
			flag = 1;
		}
	}if(flag == 1){
		cout << endl;
	}
	
	if(flag == 0){
		int sum = 0;
		for(int i=0; i<my.size()-1; i++){
			sum += dis[my[i]][my[i+1]];
		}
		cout << sum << endl;
	}
	return 0;
}

总结

两个测试点没过还是挺遗憾的,但想想其实也就刷了两三个星期的pat题,对这个结果也就挺满意了,有机会的话下次再战。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值