1. 知识点总结
1h32min实现AC成就
本次主要涉及到的知识点是字符串处理、简单贪心、并查集以及二叉搜索树的构建。
题目 | 难度 | 知识点 |
---|---|---|
1112 Stucked Keyboard | 🎯 | 字符串处理 |
1113 Integer Set Partition | 🎯 | 简单贪心 |
1114 Family Property | 🎯🎯 | 并查集 |
1115 Counting Nodes in a Binary Search Tree | 🎯🎯 | 二叉搜索树BST |
2. 分题题解
2.1 1112 Stucked Keyboard
不是很难但是思路不好的话解决起来会很麻烦。
主要思路:
- 因为出现的字符是{a-z}, {0-9} and
_
,于是在此先用函数getId将字符和对应id作简单映射 - 假设所有键都是坏的,只要某个键连续出现的次数不能被k整除,则此键正常,用
isOk
标记 - 输出结果的时候,对于坏键,每次跳跃k,好键每次跳跃1
#include<bits/stdc++.h>
using namespace std;
string str;
string word;
string sentence;
bool isOk[40]={false};//保存是否是好的
bool isChecked[40]={false};//保存已经输出的"坏键"
int id,k;
int getId(char a){
if(a<='z'&&a>='a'){
return a-'a';//0-25
}else if(a<='9'&&a>='0'){
return a-'0'+26;//26-35
}else{
return 36;
}
}
int main(){
scanf("%d",&k);
getchar();
getline(cin,str);
//检测某个字符是否每次出现都是k
int len=str.length();
int cnt=1;
str+=".";
for(int i=1;i<len+1;i++){
//更新计算连续字符
if(str[i]==str[i-1]){
cnt++;
}else{
if(cnt%k!=0){
id=getId(str[i-1]);
isOk[id]=true;
}
cnt=1;
}
}
//统计出事的
for(int i=0;i<len;){
id=getId(str[i]);
sentence+=str[i];
if(!isOk[id]){
if(!isChecked[id]){
printf("%c",str[i]);
isChecked[id]=true;
}
i+=k;
continue;
}else{
i++;
}
}
printf("\n%s",sentence.c_str());
return 0;
}
2.2 1113 Integer Set Partition
看完题目大概就可以得出简单从小到大排序,前N/2给Set2,其他给Set1可以使得Set1的和大于Set2最大化
#include<bits/stdc++.h>
using namespace std;
//最小化n1-n2 最大化S1-S2
int N,n1,n2,sum1=0,sum2=0;
vector<int>v;
int main(){
scanf("%d",&N);
v.resize(N);
for(int i=0;i<N;i++){
scanf("%d",&v[i]);
}
sort(v.begin(),v.end());
n2=N>>1;
n1=N-n2;
for(int i=0;i<n2;i++){
sum2+=v[i];
}
for(int i=n2;i<N;i++){
sum1+=v[i];
}
printf("%d %d",n1-n2,sum1-sum2);
return 0;
}
2.3 1114 Family Property
并查集模板,主要是需要另外开A
和E
数组去存每个家族的财产信息以及最后输出的时候需要新建结构体排序。
#include<bits/stdc++.h>
using namespace std;
int N,id,fid,mid,k,e,a;
vector<int>cids;
int f[10000];
int root[10000]={0};
int E[10000]={0};
int A[10000]={0};
bool exist[10000]={false};
const int maxn=9999;
struct Node{
int id;
int sum;
double avg_e,avg_a;
};
vector<Node>ans;
bool cmp(Node a,Node b){
if(a.avg_a!=b.avg_a){
return a.avg_a>b.avg_a;
}else{
return a.id<b.id;
}
}
int Find(int a){
int x=a;
while(a!=f[a]){
a=f[a];
}
while(x!=f[x]){
int temp=x;
x=f[x];
f[temp]=a;
}
return a;
}
void Union(int a,int b){
int fa=Find(a);
int fb=Find(b);
if(fa<fb){
f[fb]=fa;
root[fa]+=root[fb];
root[fb]=0;
}else if(fb<fa){
f[fa]=fb;
root[fb]+=root[fa];
root[fa]=0;
}
}
int main(){
scanf("%d",&N);
for(int i=0;i<=maxn;i++){
f[i]=i;
root[i]=1;
}
while(N--){
scanf("%d%d%d%d",&id,&fid,&mid,&k);
cids.resize(k);
for(int i=0;i<k;i++){
scanf("%d",&cids[i]);
}
scanf("%d%d",&e,&a);
//注册用户信息
exist[id]=true;
E[id]+=e;
A[id]+=a;
//将信息融合
if(mid!=-1){
Union(id,mid);
exist[mid]=true;
}
if(fid!=-1){
Union(id,fid);
exist[fid]=true;
}
for(int i=0;i<k;i++){
Union(id,cids[i]);
exist[cids[i]]=true;
}
}
for(int i=0;i<=maxn;i++){
if(exist[i]){
int r=Find(i);
if(i!=r){
E[r]+=E[i];
A[r]+=A[i];
}
}
}
Node temp;
for(int i=0;i<=maxn;i++){
if(exist[i]&&root[i]!=0){
temp.id=i;
temp.sum=root[i];
temp.avg_e=E[i]*1.0/root[i];
temp.avg_a=A[i]*1.0/root[i];
ans.push_back(temp);
}
}
sort(ans.begin(),ans.end(),cmp);
int len=ans.size();
printf("%d",len);
for(int i=0;i<len;i++){
printf("\n%04d %d %.3f %.3f",ans[i].id,ans[i].sum,ans[i].avg_e,ans[i].avg_a);
}
return 0;
}
2.4 1115 Counting Nodes in a Binary Search Tree
思路:
- 构建二叉搜索树:注意关于左孩子可以和根节点值一样
- 层次遍历存储每一层的节点值
- 最后输出倒数两层节点数大小
#include<bits/stdc++.h>
using namespace std;
int N,temp;
struct Node{
int val;
Node*left=NULL;
Node*right=NULL;
int level;
};
void Insert(Node* &root,int val){
if(root==NULL){
root=new Node;
root->val=val;
}else{
if(val<=root->val){
Insert(root->left,val);
}else if(val>root->val){
Insert(root->right,val);
}
}
return;
}
int max_level=0;
vector<vector<int> >nodes;
void levelTravel(Node*root){
queue<Node*>q;
root->level=0;
q.push(root);
while(!q.empty()){
Node*top=q.front();
if(top->level>max_level){
max_level=top->level;
}
if(top->left!=NULL){
top->left->level=top->level+1;
q.push(top->left);
}
if(top->right!=NULL){
top->right->level=top->level+1;
q.push(top->right);
}
//printf("level:%d val:%d\n",top->level,top->val);
nodes[top->level].push_back(top->val);
q.pop();
}
}
int main(){
scanf("%d",&N);
Node*root=NULL;
nodes.resize(N);
for(int i=0;i<N;i++){
scanf("%d",&temp);
Insert(root,temp);
}
levelTravel(root);
int n1=nodes[max_level].size();
int n2=nodes[max_level-1].size();
printf("%d + %d = %d",n1,n2,n1+n2);
return 0;
}
3. 参考资料
无