2021年3月9日pat刷题笔记

2021年3月9日pat刷题笔记

1.1112 Stucked Keyboard (20 分)

链接

分析:输入k和一行字符串,如果一个字符一直出现k次,则该字符的按键视为坏掉。
注意:如果前面出现了k次的倍数,但是后没有出现k次的倍数,那么该按键没有坏掉!!!

#include<bits/stdc++.h>
using namespace std;
int main(){
	vector<char> v;
	map<char, int> m;
	int k;
	cin >> k;
	string s;
	cin >> s;
	for(int i=0; i<s.size(); i++){
		int flag = 0;
		for(int j=i; j<i+k-1; j++){
			if(s[j] != s[j+1]){
				flag = 1;
			}
		}
		if(flag == 0){
			if(m.find(s[i]) == m.end()){
				m[s[i]] = 1;
				v.push_back(s[i]);
			}else{
				m[s[i]]++;
			}
			i = i + k - 1;
			continue;
		}else{
			if(m.find(s[i]) != m.end()){
				m.erase(s[i]);
				int cnt;
				for(int j=0; j<v.size(); j++){
					if(v[j] == s[i]){
						cnt = j;
						break;
					}
				}
				v.erase(v.begin()+cnt);
			}
		}
	}
	for(int i=0; i<v.size(); i++){
		cout << v[i];
	}
	cout << endl;
	for(int i=0; i<s.size(); i++){
		cout << s[i];
		if(m.find(s[i]) != m.end()){
			i = i + k - 1;
			continue;
		}
	}
	cout << endl;
	
	return 0;
} 

2.1113 Integer Set Partition (25 分)

链接

分析:输入一串数字,将其分为两份,使其个数相差最小,并且两份的各自和相差最大。水题,不多说了。

#include<bits/stdc++.h>
using namespace std;
vector<int> v;
int main(){
	int n, k;
	cin >> n;
	for(int i=0; i<n; i++){
		cin >> k;
		v.push_back(k);
	}
	sort(v.begin(), v.end());
	int sum1 = 0, sum2 = 0;
	for(int i=0; i<n/2; i++){
		sum1 += v[i];
	}
	for(int i=n/2; i<n; i++){
		sum2 += v[i];
	}
	cout << n%2 << " " << sum2-sum1 << endl;
	return 0;
}

3.1114 Family Property (25 分)

链接

分析:输入n行,每行有自己,父母,孩子和房子数量和面积,输出有几个家族成员以及各个家族的家产。
超级恶心的题,我自己用的的并查集,但是做的时候,发现后面输入的家族成员如果包含之前两个家族的话,那么需要把之前的两个家族联合起来,超级绕,并查集套来套去,我自己找不到bug
,毕竟我写的太麻烦了,可能有好的方法,测试点2与测试点4没有通过。

#include<bits/stdc++.h>
using namespace std;
struct member{
	int id, number;
	double M, A;
};
int father[1050], num[10050], MArea[1050], Area[1050], person[1050], res[1050] ,resid[1050], resM[1050], resA[1050];
member ress[1050];
void init(int n){
	for(int i=0; i<=n; i++){
		father[i] = i;
	}
}
int FindFather(int x){
	while(x != father[x]){
		x = father[x];
	}
	return x;
}
void Union(int a, int b){
	int fatha = FindFather(a);
	int fathb = FindFather(b);
	if(fatha != fathb){
		father[fatha] = fathb;
	}
}
bool cmp(member a, member b){
	if(a.A == b.A){
		return a.id < b.id;
	}
	return a.A > b.A;
}
int main(){
	int n, me, fa, mo, k, ch;
	cin >> n;
	init(n);
	for(int i=1; i<=n; i++){
		cin >> me >> fa >> mo >> k;
		vector<int> finded;
		person[i]++;
		if(num[me] != 0){
			finded.push_back(num[me]);
		}else{
			num[me] = i;
		}
		if(fa != -1) {
			person[i]++;
		}
		if(fa != -1 && num[fa] != 0){
			finded.push_back(num[fa]);
		}else{
			num[fa] = i;
		}
		if(mo != -1) {
			person[i]++;
		}
		if(mo != -1 && num[mo] != 0){
			finded.push_back(num[mo]);
		}else{
			num[mo]= i;
		}
		int temp[8];
		for(int j=1; j<=k; j++){
			person[i]++;
			cin >> ch;
			temp[j] = ch;
			if(num[ch] != 0){
				finded.push_back(num[ch]);
			}else{
				num[ch]= i;
			}
		}
		if(finded.size() > 1){
			for(int j=0; j<finded.size()-1; j++){
				Union(finded[j], finded[j+1]);
			}
		}
		if(finded.size() >= 1){
			Union(i, finded[0]);
		}
		num[me] = num[fa] = num[mo] = i;
		for(int j=1; j<=k; j++){
			num[temp[j]] = i;
		}
		cin >> MArea[i] >> Area[i];
	}
	for(int i=0; i<=10000; i++){
		if(num[i] != 0){
			num[i] = father[num[i]];
			res[father[num[i]]]++;
			if(resid[father[num[i]]] == 0){
				resid[father[num[i]]] = i;
			}
		}
	}
	for(int i=1; i<=n; i++){
		resM[father[i]] += MArea[i];
		resA[father[i]] += Area[i];
	}
	int cnt=0;
	for(int i=1; i<=n; i++){
		if(res[i] != 0){
			member temp;
			temp.id = resid[i];
			temp.number = res[i];
			temp.M = resM[i]*1.000/res[i];
			temp.A = resA[i]*1.000/res[i];
			ress[cnt++] = temp;
		}
	}
	sort(ress, ress+cnt, cmp);
	cout << cnt << endl;
	for(int i=0; i<cnt; i++){
		printf("%04d %d %.3f %.3f\n", ress[i].id, ress[i].number, ress[i].M, ress[i].A);
	}
	return 0;
}

4.1115 Counting Nodes in a BST (30 分)

链接

分析:输入一串数,将它们按顺序构成一颗二叉搜索树。感觉上作为一道30分题,有点不够格,还没上一题有难度。按递归来构建二叉搜索树。
注意:保存深度的数组一定开得大,不然会越界。二叉搜索树是左子树小于等于父节点,我之前都记反了, 参考了点柳神的。

#include<bits/stdc++.h>
using namespace std;
struct Node{
	Node *left, *right;
	int val;
}*root;
int dep[1000], max_dep = -1;
Node* Insert(Node* root, int node, int depth){
	if(root == NULL){
		root = new Node();
		root->val = node;
		if(max_dep < depth){
			max_dep = depth;
		}
		dep[depth]++;
	}else{
		if(root->val < node){
			root->right = Insert(root->right, node, depth+1);
		}else{
			root->left = Insert(root->left, node, depth+1);
		}
	}
	return root;
}
int main(){
	int n, node;
	cin >> n;
	for(int i=0; i<n; i++){
		cin >> node;
		root = Insert(root, node, 0);
	}
	printf("%d + %d = %d\n", dep[max_dep], dep[max_dep-1], dep[max_dep]+dep[max_dep-1]);
	return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值