PAT A1140~A1143

3 篇文章 0 订阅

一、PAT A1140 Look-and-say Sequence

  1. 就是简单的模拟啦。参考代码如下。
#include<iostream>
#include<string>
using namespace std;

int main() {
	int d, n;
	string s;
	cin >> d >> n;
	s = '0' + d;
	while (--n) {
		string t;
		int i = 0;
		while (i < s.size()) {
			t += s[i++];
			int cnt = 1;
			while (i < s.size() && s[i] == s[i - 1]) {
				cnt++;
				i++;
			}
			t += '0' + cnt;
		}
		s = t;
	}
	cout << s << endl;
	return 0;
}

二、PAT A1141 PAT Ranking of Institutions

  1. 散列的思想,读入数据时就按学校将考生分类,然后再排序。参考代码如下。
#include<cstdio>
#include<string>
#include<unordered_map>
#include<vector>
#include<algorithm>
#include<cctype>
#include<cstring>
using namespace std;
const float eps = 1e-3;

struct institution {
	int rank, NS = 0;
	string school;
	float TWS = 0;
};
bool cmp(institution &i1, institution &i2) {
	if ((int)i1.TWS != (int)i2.TWS)
		return i1.TWS > i2.TWS;
	else if (i1.NS != i2.NS)
		return i1.NS < i2.NS;
	else return i1.school < i2.school;
}

unordered_map <string, institution> m;
vector <institution> v;

int main() {
	int n, score;
	string id, school;
	id.resize(8);
	school.resize(8);
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		memset(&id[0], '\0', 8);
		memset(&school[0], '\0', 8);
		scanf("%s%d%s", &id[0], &score, &school[0]);
		for (int i = 0; school[i] != '\0'; i++) school[i] = tolower(school[i]);
		m[school].NS++;
		m[school].school = school;
		if (id[0] == 'T') m[school].TWS += 1.5*score;
		else if (id[0] == 'A') m[school].TWS += score;
		else m[school].TWS += score / 1.5;
	}
	for (auto it : m) v.push_back(it.second);
	sort(v.begin(), v.end(), cmp);
	printf("%d\n", v.size());
	int i = 0;
	while (i < v.size()) {
		v[i].rank = i + 1;
		i++;
		while (i < v.size() && (int)v[i].TWS == (int)v[i - 1].TWS) {
			v[i].rank = v[i - 1].rank;
			i++;
		}
	}
	for (auto it : v)
		printf("%d %s %d %d\n", it.rank, &it.school[0], (int)it.TWS, it.NS);
	return 0;
}

三、PAT A1142 Maximal Clique

  1. 判断是否为最大连通分量。首先判断是否连通,如果连通,则尝试将每一个不在连通分量中的顶点加入该连通分量中,若加入后仍是连通分量,则说明不是最大连通分量。参考代码如下。
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 210;

bool G[maxn][maxn], in_clique[maxn];
int Nv, Ne, M, K;
int v[maxn];

int main() {
	fill(G[0], G[0] + maxn * maxn, false);
	scanf("%d%d", &Nv, &Ne);
	int v1, v2;
	while (Ne--) {
		scanf("%d%d", &v1, &v2);
		G[v1][v2] = G[v2][v1] = true;
	}
	scanf("%d", &M);
	while (M--) {
		fill(in_clique, in_clique + maxn, false);
		scanf("%d", &K);
		for (int i = 1; i <= K; i++) {
			scanf("%d", &v[i]);
			in_clique[v[i]] = true;
		}
		bool clique = true;
		for (int i = 1; i <= K; i++) {
			if(clique)
				for (int j = i + 1; j <= K; j++) {
					if (!G[v[i]][v[j]]) {
						clique = false;
						break;
					}
				}
		}
		if (clique) {
			bool max_clique = true;
			for (int i = 1; i <= Nv; i++) {
				if (!in_clique[i]) {
					int j = 1;
					while (j <= K) {
						if (G[i][v[j]]) j++;
						else break;
					}
					if (j == K + 1) {
						max_clique = false;
						break;
					}
				}
			}
			if (max_clique) printf("Yes\n");
			else printf("Not Maximal\n");
		}
		else printf("Not a Clique\n");
	}
	return 0;
}

四、PAT A1143 Lowest Common Ancestor

  1. 这题我一开始的思路是建树,然后寻找每个结点的祖先,然后再比较判断。花了一个多小时弄完后发现最后一个测试点会超时,死活都过不去。后来翻看了这个萌妹子的博客,发现思路非常精巧。BST 先序序列中第一个值在 a 和 b 之间的结点即为 a, b 的最近共同祖先(可以想象 BST 的中序遍历,a, b 的共同祖先一定在 a 和 b 之间,先序遍历可以保证找到的第一个值为 a, b 的最近共同祖先)。参考代码如下。
  2. #include<cstdio>
    #include<unordered_map>
    using namespace std;
    const int maxn = 10010;
    
    unordered_map <int, bool> m;
    int pre[maxn];
    
    int main() {
    	int M, N, u, v, t;
    	scanf("%d%d", &M, &N);
    	for (int i = 0; i < N; i++) {
    		scanf("%d", &pre[i]);
    		m[pre[i]] = true;
    	}
    	while (M--) {
    		scanf("%d%d", &u, &v);
    		if (!m[u] && !m[v])
    			printf("ERROR: %d and %d are not found.\n", u, v);
    		else if (!m[u] && m[v])
    			printf("ERROR: %d is not found.\n", u);
    		else if (m[u] && !m[v])
    			printf("ERROR: %d is not found.\n", v);
    		else {
    			for (int i = 0; i < N; i++) {
    				t = pre[i];
    				if ((u <= t && t <= v) || (v <= t && t <= u))
    					break;
    			}
    			if (t == u)
    				printf("%d is an ancestor of %d.\n", u, v);
    			else if (t == v)
    				printf("%d is an ancestor of %d.\n", v, u);
    			else
    				printf("LCA of %d and %d is %d.\n", u, v, t);
    		}
    	}
    	return 0;
    }
    
  3. 这里也把我的非常复杂的代码贴在这里,以供参考。
//未通过
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 10010;
struct node {
	int v;
	node* parent = NULL;
	node* lchild = NULL;
	node* rchild = NULL;
};

int pre[maxn], in[maxn];

node* build(int preL, int preR, int inL, int inR) {
	if (preL > preR) return NULL;
	node* root = new node;
	root->v = pre[preL];
	int k;
	for (k = inL; k != inR; k++)
		if (in[k] == pre[preL]) break;
	int num = k - inL;
	root->lchild = build(preL + 1, preL + num, inL, k - 1);
	root->rchild = build(preL + num + 1, preR, k + 1, inR);
	if (root->lchild) root->lchild->parent = root;
	if (root->rchild) root->rchild->parent = root;
	return root;
}

node* search(node* root, int n) {
	if (root == NULL) return NULL;
	if (n == root->v) return root;
	else if (n < root->v) return search(root->lchild, n);
	else return search(root->rchild, n);
}

int main() {
	int M, N, u, v;
	scanf("%d%d", &M, &N);
	for (int i = 0; i < N; i++) {
		scanf("%d", &pre[i]);
		in[i] = pre[i];
	}
	sort(in, in + N);
	node* BST = build(0, N - 1, 0, N - 1);
	while (M--) {
		scanf("%d%d", &u, &v);
		node* nu = search(BST, u);
		node* nv = search(BST, v);
		if (nu == NULL && nv == NULL)
			printf("ERROR: %d and %d are not found.\n", u, v);
		else if (nu != NULL && nv == NULL)
			printf("ERROR: %d is not found.\n", v);
		else if (nu == NULL && nv != NULL)
			printf("ERROR: %d is not found.\n", u);
		else {
			vector <int> ancestor_u;
			bool found = false;
			while (nu && !found) {
				if (nu->v == v) {
					printf("%d is an ancestor of %d.\n", v, u);
					found = true;
				}
				ancestor_u.push_back(nu->v);
				nu = nu->parent;
			}
			while (nv && !found) {
				if (nv->v == u) {
					printf("%d is an ancestor of %d.\n", u, v);
					found = true;
				}
				else for (int i = 1; i < ancestor_u.size(); i++)
					if (nv->v == ancestor_u[i]) {
						printf("LCA of %d and %d is %d.\n", u, v, ancestor_u[i]);
						found = true;
						break;
					}
				nv = nv->parent;
			}
		}
	}
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值