数据结构与算法训练:第二十二弹

1. 知识点总结

耗时:1h22min

得分:100/100

主要考察:字符串处理、多叉树的层次遍历、数组、结构体排序(模拟)

总体上偏简单的一套题目

题目难度知识点
1092 To Buy or Not to Buy🎯字符串统计
1093 Count PAT’s🎯字符串统计
1094 The Largest Generation🎯树的层次遍历
1095 Cars on Campus🎯模拟

2. 分题题解

2.1 1092 To Buy or Not to Buy

主要是字符串的统计问题,这里其实getId也可以直接用map去替代,如果给定字符串包含目标字符串的所有字符,则输出Yes并且输出多出来的字符个数;如果缺少则输出缺少字符的个数

#include<bits/stdc++.h>
using namespace std;
string a,b;
int getId(char c){
	if(isdigit(c)){
		return c-'0';
	}else{
		if(c<='Z'&&c>='A'){
			return c-'A'+10;
		}else{
			return c-'a'+36;
		}
	}
}
int lena,lenb;
int cnt[100]={0};
int pos=0,neg=0;
int main(){
	cin>>a>>b;
	lena=a.length();
	lenb=b.length();
	for(int i=0;i<lena;i++){
		cnt[getId(a[i])]++;
	}
	for(int i=0;i<lenb;i++){
		cnt[getId(b[i])]--;
	}
	for(int i=0;i<70;i++){
		if(cnt[i]>0){
			pos+=cnt[i];
		}else{
			neg-=cnt[i];
		}
	}
	if(neg==0){
		printf("Yes %d",pos);
	}else{
		printf("No %d",neg);
	}
	return 0;
} 

1093 Count PAT’s

这道题可以这样考虑,在已知A的情况下,得到这个位置的A的前面有p个P,后面有t个T,用数组来存这个信息,则对于这个位置的A所组成的PAT个数为 p × t p×t p×t,最终将所有A位置可能得到的PAT个数相加得到最后的结果

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mod=1000000007;
ll ans=0;
int len;
string str;
vector<int>p,t;
vector<int>posA;//存储A的位置 
int main(){
	cin>>str; 
	len=str.length();
	p.resize(len,0);//在位置i之前的P的个数
	t.resize(len,0);//在位置i之后的T的个数 
	int cnt=0;
	for(int i=0;i<len;i++){
		p[i]=cnt;
		if(str[i]=='A'){
			posA.push_back(i);
		}
		if(str[i]=='P'){
			cnt++;
		}
	} 
	cnt=0;
	for(int i=len-1;i>=0;i--){
		t[i]=cnt;
		if(str[i]=='T'){
			cnt++;
		}
	} 
	for(int i=0;i<posA.size();i++){
		int pos=posA[i];
		ans=(ans+(p[pos]*t[pos])%mod)%mod; 
	}
	printf("%lld",ans);
	return 0;
}

2.3 1094 The Largest Generation

其实不用Node也可以,主要是构建树以及层次遍历记录每一层的节点个数

#include<bits/stdc++.h>
using namespace std;
struct Node{
	vector<int>childs;
	int len=0;
	int level=0;
};
vector<Node>nodes;
int N,M,K,id;
int root=1;
vector<int>level;
void levelTravel(int root){
	queue<int>q;
	q.push(root);
	while(!q.empty()){
		int id=q.front();
		q.pop();
		level[nodes[id].level]++;
		for(int i=0;i<nodes[id].len;i++){
			nodes[nodes[id].childs[i]].level=nodes[id].level+1;
			q.push(nodes[id].childs[i]);
		}
	}
}
int main(){
	scanf("%d%d",&N,&M);
	nodes.resize(N+1);
	level.resize(N+1,0);
	for(int i=0;i<M;i++){
		scanf("%d",&id);
		scanf("%d",&nodes[id].len);
		nodes[id].childs.resize(nodes[id].len);
		for(int j=0;j<nodes[id].len;j++){
			scanf("%d",&nodes[id].childs[j]);
		}
	}
	levelTravel(root);
	int max_g,max_num=0;
	for(int i=0;i<N+1;i++){
		if(level[i]>max_num){
			max_num=level[i];
			max_g=i;
		}
	}
	printf("%d %d",max_num,max_g+1);
	return 0;
}

2.4 1095 Cars on Campus

不涉及复杂的数据结构,属于比较基础的模拟。

首先需要从输入的信息按车牌号、时间排序,提取出合法的停车信息记录到period中,对period按照时间排序,然后对于每一个时间节点进行遍历得到该时间节点停车场车子的数量

最后按照字符顺序输出停车最长时间的车牌号以及对应的停车时长。

#include<bits/stdc++.h>
using namespace std;
//输出每一个时间停车的数量
//最后一行输出最长停车时间的车子
struct Node{
	string name;
	int t;
	bool state=false;//状态 
}; 
struct Period{
	int st;
	int ed;
	string name;
};
int N,M,hh,mm,ss;
string name,state,str;
Period temp;
Node pre;
vector<Node>nodes;
vector<Period>period;//记录一辆车的停车过程 
map<string,int>mp;
int max_t=0;
vector<string>ans;
bool cmp1(Node a,Node b){
	if(a.name!=b.name){
		return a.name<b.name;
	}else{
		return a.t<b.t;
	}
}
bool cmp2(Period a,Period b){
	return a.st<b.st;
}
int main(){
	scanf("%d%d",&N,&M);
	nodes.resize(N);
	for(int i=0;i<N;i++){
		cin>>name;
		cin>>hh;
		getchar();
		cin>>mm;
		getchar();
		cin>>ss;
		cin>>state;
		nodes[i].name=name;
		nodes[i].t=3600*hh+60*mm+ss;
		if(state=="in"){
			nodes[i].state=true;
		}
	}
	sort(nodes.begin(),nodes.end(),cmp1);
	//记录合法的停车记录 
	for(int i=0;i<N;i++){
		if(nodes[i].state){
			pre=nodes[i];
		}else{
			if(nodes[i].name==pre.name&&pre.state==true){
				temp.st=pre.t;
				temp.ed=nodes[i].t;
				temp.name=pre.name;
				period.push_back(temp);
				if(mp.find(pre.name)!=mp.end()){
					mp[pre.name]+=nodes[i].t-pre.t;
				}else{
					mp[pre.name]=nodes[i].t-pre.t;
				}
				pre.state=false;
			}
		}
	}
	sort(period.begin(),period.end(),cmp2);
	int total=period.size();
	for(int i=0;i<M;i++){
		scanf("%d:%d:%d",&hh,&mm,&ss);
		int t=hh*3600+mm*60+ss;
		int cnt=0;
		for(int j=0;j<total;j++){
			if(period[j].st>t){
				break;
			}else{
				if(period[j].ed>t){
					cnt++;
				}
			}
		}
		printf("%d\n",cnt);
	}
	for(map<string,int>::iterator it=mp.begin();it!=mp.end();it++){
		if(it->second>max_t){
			max_t=it->second;
			ans.clear();
			ans.push_back(it->first);
		}else if(it->second==max_t){
			ans.push_back(it->first);
		}
	}
	sort(ans.begin(),ans.end());
	for(int i=0;i<ans.size();i++){
		printf("%s ",ans[i].c_str());
	}
	printf("%02d:%02d:%02d",max_t/3600,(max_t-max_t/3600*3600)/60,max_t%60);
	return 0;
}

3. 参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值