PTA刷题日记16

1151 LCA in a Binary Tree (30 分)

跟1143一样直接建树就22分,所以我没有建树,而是去看别人怎么写…
给定中序以后因为能确定根的话,只要找到这两个数的根即可,也就是在中序数组中位置夹在u,v之间,只要出现一个就一定是,所以用一个map存储位置即可

#include<bits/stdc++.h> 
using namespace std;
const int N = 1e4 + 5;
unordered_map<int, int> mp;
int pre[N], in[N], res, pu, pv;

void find(int inL, int inR, int preL, int preR) {
	if(preL > preR) return;
	int root = pre[preL];
	int pos = mp[root];
	if(pu <= pos && pos <= pv) {
		res = root;
		return;
	}
	int numl = pos - inL;
	find(inL, pos-1, preL+1, preL+numl);
	find(pos+1, inR, preL+1+numl, preR);
}

int main() {
	int n, m, u, v;
	scanf("%d %d",&m,&n);
	for(int i = 0; i < n; i++) {
		scanf("%d",in+i);
		mp[in[i]] = i;
	}
	for(int i = 0; i < n; i++) scanf("%d",pre+i);
	for(int i = 0; i < m; i++) {
		scanf("%d %d",&u,&v);
		if(mp.count(u) == 0 && mp.count(v) == 0) printf("ERROR: %d and %d are not found.\n",u,v);
		else if(mp.count(u) == 0) printf("ERROR: %d is not found.\n", u);
		else if(mp.count(v) == 0) printf("ERROR: %d is not found.\n", v);
		else {
			pu = mp[u];
			pv = mp[v];
			if(pu > pv) swap(pu, pv);
			find(0, n-1, 0, n-1);
			if(res != u && res != v) printf("LCA of %d and %d is %d.\n",u, v, res);
			else if(res == u) printf("%d is an ancestor of %d.\n",res, v);
			else printf("%d is an ancestor of %d.\n",res, u);
		}
	}
	return 0;
}
/*
6 8
7 2 3 4 6 5 1 8
5 3 7 2 6 4 8 1
2 6
8 1
7 7
12 -3
0 8
99 99
LCA of 2 and 6 is 3.
8 is an ancestor of 1.
7 is an ancestor of 7.
ERROR: 12 and -3 are not found.
ERROR: 0 is not found.
ERROR: 99 and 99 are not found.
*/

1152 Google Recruitment (20 分)

经过我大量尝试终于找到测试点4是为什么了,当l小于k的时候即使这个数是质数也是输出“404”,所以判对条件也要加一个l >= k
测试点2和5是因为要遍历到最后一个位置才有答案,如果没处理最后一个数这两个测试点会错

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

void s2i(string s, ll &n) {
	stringstream ss;
	ss << s;
	ss >> n;
}

void i2s(string &s, ll n) {
	stringstream ss;
	ss << n;
	ss >> s;
}

bool isp(ll n) {
	if(n < 2) return false;
	for(ll i = 2; i <= sqrt(n); i++) {
		if(n % i == 0) return false;
	}
	return true;
}

int main() {
	bool f = 0;
	string n;
	ll l, k, t;
	cin >> l >> k >> n;
	ll p = pow(10, k-1);
	s2i(n.substr(0, k), t);
	for(int i = k; i < n.length() && !f; i++) {
		if(isp(t)) f = 1;
		else {
			t %= p;
			t *= 10;
			t += n[i] - '0';
		}
	}
	if(isp(t)) f = 1;
	if(f && l >= k) {
		string ss;
		i2s(ss, t);
		for(int i = 0; i < k-ss.length(); i++) printf("0");
		printf("%d",t);
	}
	else printf("404");
	return 0;
}

这么写也是对的

s2i(n.substr(0, k-1), t);
	for(int i = k-1; i < n.length(); i++) {
		t %= p;
		t *= 10;
		t += n[i] - '0';
		if(isp(t)) {
			f = 1;	
			break;
		}
	}

1153 Decode Registration Card of PAT (25 分)

注意结果集是空的就要输出NA,所以三种查询都有可能会出现NA
强烈注意某些集合,例如ans使用前一定要重新声明,否则会有一个超时,一个错误

简洁一点的代码
#include<bits/stdc++.h>
using namespace std;
struct node{
	string id;
	int score;
	friend bool operator<(node a, node b) {
		if(a.score == b.score) return a.id < b.id;
		else return a.score > b.score;
	}
};
vector<node> v;

int main() {
	int n, m, sco;
	cin >> n >> m;
	string s;
	for(int i = 0; i < n; i++) {
		cin >> s >> sco;
		v.push_back({s,sco});
	}
	for(int i = 1; i <= m; i++) {
		int ty, tot = 0, cnt = 0;
		cin >> ty >> s;
		vector<node> ans;
		printf("Case %d: %d %s\n",i,ty, s.c_str());
		switch(ty) {
			case 1:{
				for(int j = 0; j < n; j++) {
					if(s[0] == v[j].id[0]) ans.push_back(v[j]);
				}
				if(ans.size() == 0) printf("NA\n");
				else sort(ans.begin(), ans.end());
				break;
			}
			case 2:{
				for(int j = 0; j < n; j++) {
					if(s == v[j].id.substr(1,3)) {
						cnt++;
						tot += v[j].score;
					}
				}
				if(cnt) printf("%d %d\n",cnt, tot);	
				else printf("NA\n");
				break;
			}
			case 3:{
				unordered_map<string, int> mp;
				for(int j = 0; j < n; j++) {
					if(s == v[j].id.substr(4, 6)) mp[v[j].id.substr(1,3)]++;
				}
				for(auto it: mp) ans.push_back({it.first, it.second});
				if(ans.size() == 0) printf("NA\n");
				else sort(ans.begin(), ans.end());
				break;
			}
		}
		for(int j = 0; j < ans.size(); j++) {
			printf("%s %d\n",ans[j].id.c_str(), ans[j].score);
		}
	}
	return 0;
}
并没有变快的垃圾代码
#include<bits/stdc++.h>
using namespace std;
struct node{
	string id;
	int score;
	friend bool operator<(node a, node b) {
		if(a.score == b.score) return a.id < b.id;
		else return a.score > b.score;
	}
};
vector<node> level[300];
unordered_map<string, vector<node> >site, date;

int main() {
	int n, m, sco;
	cin >> n >> m;
	string s = "", t;
	for(int i = 0; i < n; i++) {
		cin >> s >>sco;
		node tem = {s, sco};
		level[s[0]].push_back(tem);
		t = s.substr(1, 3);
		site[t].push_back(tem);
		t = s.substr(4, 6);
		date[t].push_back(tem);
	}
	int ty;
	for(int i = 1; i <= m; i++) {
		cin >> ty >> s;
		printf("Case %d: %d ",i,ty);
		cout<<s<<endl;
		switch(ty) {
			case 1:{
				int ind = s[0];
				if(level[ind].size() == 0) printf("NA\n");
				else {
					sort(level[ind].begin(), level[ind].end());
					for(int j = 0; j < level[ind].size(); j++) {
						printf("%s %d\n",level[ind][j].id.c_str(), level[ind][j].score);
					}	
				}
				break;
			}
			case 2:{
				if(site.count(s) == 0) printf("NA\n");
				else {
					int tot = 0;
					for(auto it:site[s]) {
						tot += it.score;
					}
					printf("%d %d\n",site[s].size(), tot);	
				}
				break;
			}
			case 3:{
				if(date.count(s) == 0) printf("NA\n");
				else {
					vector<node> ans;
					unordered_map<string, int> mp;
					int p;
					for(auto it:date[s]) {
						mp[it.id.substr(1,3)]++;
					}
					for(auto it: mp) {
						ans.push_back({it.first, it.second});
					}
					sort(ans.begin(), ans.end());
					for(int j = 0; j < ans.size(); j++) {
						printf("%s %d\n",ans[j].id.c_str(), ans[j].score);
					}
				}
				break;
			}
		}
	}
	return 0;
}

1155 Heap Paths (30 分)

那段从根往上顺的操作应该写个函数精简一下的,但是我太懒了,就这样吧。。。
这题采用了跟1147不一样的方法,从叶子结点往上读取,就是要先读右跟会有点烦,其实应该可以用dfs写,深度遍历下去,每次都先往右结点去即可,但是这样用循环写也是可以的

#include<bits/stdc++.h>
using namespace std;
int n, heap[1005];

int main() {
	scanf("%d",&n);
	for(int i = 1; i <= n; i++) scanf("%d", heap+i);
	int l = log(n) / log(2), p1 = pow(2, l), p = n/2 + 1, d, f;
	bool book = 0;
	if(heap[1] > heap[n]) d = 1;//大 
	else d = -1;//小 
	for(int i = p1-1; i > n/2; i--) {
		vector<int> ans;
		int e = i;
		while(e >= 2) {
			ans.push_back(heap[e]);
			if(heap[e] > heap[e/2]) f = -1;
			else if(heap[e] < heap[e/2]) f = 1;
			else f = d;
			e /= 2;
			if(f*d < 0) book = 1;
		}
		ans.push_back(heap[1]);
		for(int j = ans.size()-1; j >= 0; j--) {
			printf("%d", ans[j]);
			if(j) printf(" ");
		}
		printf("\n");
	}
	for(int i = n; i >= p1; i--) {
		vector<int> ans;
		int e = i;
		while(e >= 2) {
			ans.push_back(heap[e]);
			if(heap[e] > heap[e/2]) f = -1;
			else if(heap[e] < heap[e/2]) f = 1;
			else f = d;
			e /= 2;
			if(f*d < 0) book = 1;
		}
		ans.push_back(heap[1]);
		for(int j = ans.size()-1; j >= 0; j--) {
			printf("%d", ans[j]);
			if(j) printf(" ");
		}
		printf("\n");
	}
	if(book) printf("Not Heap\n");
	else {
		if(d > 0) printf("Max Heap\n");
		else printf("Min Heap\n");
	}
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值