PAT A1132~A1135

2 篇文章 0 订阅

一、PAT A1132 Cut Integer

  1. 就是模拟啦。注意判断分割的两个数乘积为 0 的情况。参考代码如下。
#include<iostream>
#include<string>
#include<cstring>
using namespace std;

int main() {
	string s;
	int n;
	cin >> n;
	while (n--) {
		cin >> s;
		int a = stoi(string(s.begin(), s.begin() + s.size() / 2));
		int b = stoi(string(s.begin() + s.size() / 2, s.end()));
		int c = stoi(s);
		if (a * b == 0)
			cout << "No" << endl;
		else if (c % (a * b) == 0)
			cout << "Yes" << endl;
		else cout << "No" << endl;
	}
	return 0;
}

二、PAT A1133 Splitting A Linked List

  1. 先散列把整个链表存起来,然后再遍历一次链表进行分类存储,最后输出即可。参考代码如下。
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<unordered_map>
using namespace std;

struct node {
	string address, next;
	int v;
};

unordered_map <string, node> mp;
vector <node> below_zero;
vector <node> below_k;
vector <node> above_k;
vector <node> ans;

int main() {
	string st, address, next;
	st.resize(6);
	address.resize(6);
	next.resize(6);
	int n, k, v;
	scanf("%s%d%d", &st[0], &n, &k);
	for (int i = 0; i < n; i++) {
		scanf("%s%d%s", &address[0], &v, &next[0]);
		node temp;
		temp.address = address;
		temp.next = next;
		temp.v = v;
		mp[address] = temp;
	}
	while (true) {
		if (mp[st].v < 0)
			below_zero.push_back(mp[st]);
		else if (mp[st].v <= k)
			below_k.push_back(mp[st]);
		else
			above_k.push_back(mp[st]);
		if (mp[st].next[0] == '-')	break;
		else st = mp[mp[st].next].address;
	}
	for (auto it : below_zero) ans.push_back(it);
	for (auto it : below_k) ans.push_back(it);
	for (auto it : above_k) ans.push_back(it);
	for (int i = 0; i < ans.size() - 1; i++)
		printf("%s %d %s\n", &ans[i].address[0], ans[i].v, &ans[i + 1].address[0]);
	printf("%s %d -1\n", &ans[ans.size() - 1].address[0], ans[ans.size() - 1].v);
	return 0;
}

三、PAT A1134 Vertex Cover

  1. 用邻接矩阵存储图,同时记录每个点的度。遍历 cover ,把 cover 内的每个点 u 及与 u 相连的点 v 的度减 1。最后若还有度大于 0 的点,说明不是 cover。参考代码如下。
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int maxn = 10010;

vector <int> adj[maxn];
int degree[maxn], temp_d[maxn];

int main() {
	int n, m, k, u, v;
	scanf("%d%d", &n, &m);
	while (m--) {
		scanf("%d%d", &u, &v);
		adj[u].push_back(v);
		adj[v].push_back(u);
		degree[u]++;
		degree[v]++;
	}
	scanf("%d", &k); 
	while (k--) {
		int nv;
		memcpy(temp_d, degree, sizeof(degree));
		scanf("%d", &nv);
		while (nv--) {
			scanf("%d", &u);
			for (int i = 0; i < adj[u].size(); i++) {
				v = adj[u][i];
				temp_d[u]--;
				temp_d[v]--;
			}
		}
		bool yes = true;
		for (int i = 0; i < n; i++)
			if (temp_d[i] > 0) {
				printf("No\n");
				yes = false;
				break;
			}
		if (yes) printf("Yes\n");
	}
	return 0;
}

四、PAT A1135 Is It A Red-Black Tree

  1. 这道题又参考了萌妹子的博客。“从任意结点到叶子结点的路径中,黑色结点的个数是否相同”,这个条件一开始理解错了,以为是任意根到叶子的路径中的黑色结点的个数相同,结果错的好惨。这里用 cnt 函数获取每个结点的左右孩子的黑高度,如果不相等则不为红黑树。这里也求出了每一条根到叶子的路径,如果路径上有连着的两个红色结点,则不为红黑树。写得比较复杂,参考代码如下。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;

struct node {
	int v, color;
	node* lchild = NULL;
	node* rchild = NULL;
};
vector<int> path;
bool flag = true;

void build(node* &tree, int v) {
	if (tree == NULL) {
		tree = new node;
		if (v > 0) tree->color = 1;
		else tree->color = -1;
		tree->v = abs(v);
		return;
	}
	if (abs(v) < tree->v) build(tree->lchild, v);
	else build(tree->rchild, v);
}
int cnt(node* tree) {
	if (tree == NULL) return 0;
	if (tree->color == -1) return max(cnt(tree->lchild), cnt(tree->rchild));
	else return 1 + max(cnt(tree->lchild), cnt(tree->rchild));
}
void judge(node* tree) {
	if (cnt(tree->lchild) != cnt(tree->rchild)) { flag = false; return; }
	if (tree->lchild == NULL && tree->rchild == NULL) {
		path.push_back(tree->color);
		for (int i = 0; i < path.size(); i++)
			if (i != 0 && path[i] == -1 && path[i - 1] == -1){
				flag = false; 
				return;
			}
		path.pop_back();
	}
	path.push_back(tree->color);
	if (tree->lchild) judge(tree->lchild);
	if (tree->rchild) judge(tree->rchild);
	path.pop_back();
}

int main() {
	int k, n, t;
	scanf("%d", &k);
	while (k--) {
		path.clear();
		flag = true;
		node* tree = NULL;
		scanf("%d", &n);
		for (int i = 0; i < n; i++) {
			scanf("%d", &t);
			build(tree, t);
		}		
		if (tree->color == -1) printf("No\n");
		else {
			judge(tree);
			if(flag) printf("Yes\n");
			else printf("No\n");
		} 
	}
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值