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;
}