wtpavssite

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

SMU Spring 天梯赛5题解

7.爆气球

题意:

给出n个递增的气球的坐标(可以为负数),再给出小孩的可以覆盖的长度,求出小孩子应该在哪个坐标开始覆盖能压爆最多的气球,如果坐标点不唯一则输出最小的坐标

思路:

计算每个气球作为起点的时候能压爆的气球的数量,维护出最小的气球坐标。最后特殊判断如果这个气球作为起点他的长度是不是有多余的,如果有则应该输出的坐标减去多余的长度

代码:

点击查看代码
int main(){
	int n,h;
	cin>>n>>h;
	vector<int>a(n);
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	int mx=-1;
	int posl;
	int posr;
	for(int i=0;i<n;i++){
		int cnt=1;
		int index;
		for(int j=i+1;j<n;j++){
			if(a[j]<=a[i]+h){
				cnt++;
				index=j;
			}
			else break;
		}
		if(cnt>mx){
			mx=cnt;
			posl=a[i];
			posr=a[index];
		}
	}
	int ans=posl;
	if(posl+h>posr){
		ans-=posl+h-posr;
	}
	cout<<ans<<' '<<mx;	
}

8.帅到没朋友

题意:

给出n行,每行前面一个数字k代表后面有k个输入的编号,每行代表编号上的人是在一个朋友圈里面,然后给出m行,每行一个编号,如果这个编号的人不在任何的朋友圈里面说明他很帅,或者这个人自己一个人在一个朋友圈并且不在其他的朋友圈,也说明他很帅。然后根据输入顺序输出很帅的人,如果没有人很帅,则额外输出

思路:

发现只要出现了的人就在朋友圈里面,所以使用set来实现,我们实际只需要处理k>2的情况,如果k=1的话,如果后面这个人在其他的朋友圈里面也会被标记有朋友,后续查询的时候,就算查到他也不会出错

代码:

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	cin>>n;
	set<string>has;
	while(n--){
		int k;
		cin>>k;
		if(k>1){
			while(k--){
				string s;
				cin>>s;
				has.insert(s);
			}
		}else{
			string s;
			cin>>s;
		}
	}
	vector<string>ans;
	set<string>vis;
	int m;
	cin>>m;
	while(m--){
		string id;
		cin>>id;
		if(!has.count(id)&&!vis.count(id)){
			ans.push_back(id);
			vis.insert(id);
		}
	}
	if(ans.empty()){
		cout<<"No one is handsome"<<endl;
	}else{
		for(int i=0;i<ans.size();i++){
			cout<<ans[i];
			if(i!=ans.size()-1)
				cout<<' ';
		}
		cout<<endl;
	}
}

9.海盗分赃

题意:

有p个海盗分d颗钻石。首先由序号小的海盗来分配所有人的获得的个数,如果这个分配的人得不到一半以上的人的支持就会被杀死,接着由下一个人来分配。直到分配完毕。海盗们不仅都非常聪明还按照以下原则行动:
“聪明”与“贪婪”假定:每个海盗总能够以本人利益最大化作为行为准则;
“人性化”假定:在能够取得尽量多钻石的情况下,海盗不会故意致同伙于死地;
“无偏见”假定:海盗之间没有个人恩怨,分给其他海盗钻石的次序以小序号优先为原则。
叫我们输出第一个海盗分配给自己的钻石数量

思路:

首先从海盗最少的情况来看,能轻易知道一个海盗的时候他给自己分配全部,两个海盗的时候,第一个海盗为了活命只能给下一个海盗全部的钻石。那么我们建立一个数组记录如果当前的海盗被投死之后进入下一轮的话每个海盗能得到的钻石。知道这个的话,第一个海盗就需要在这些里面选出自己不被投死的数量的需求最小的海盗,分别给他们比下一轮还要多一颗的钻石,这样就能保证这一轮他们不会把自己投票出去

代码:

点击查看代码
int main(){
	int d,p;
	cin>>d>>p;
	vector<int>q;
	q.push_back(d);
	q.push_back(0);
	for(int i=3;i<=p;i++){
		sort(q.begin(),q.end());
		int need=i/2;
		int can=d;
		for(int j=0;j<need;j++){
			q[j]=min(can,q[j]+1);
			can-=q[j];
		}
		for(int j=need;j<q.size();j++){
			q[j]=0;
		}
		q.push_back(can);
	}
	cout<<q.back()<<endl;
}

10.取行李

题意:

给出一个旅客的队列,对于第i个旅客他的行李的编号是i,如果这个旅客到达队列的头部的时候,行李的头部不是自己的行李,则这个旅客回到队伍的最后面,行李不动。输出清空行李需要的总时间,和旅客等待的平均时间(保留小数点后一位)

思路:

模拟即可

代码:

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	double n;
	cin>>n;
	queue<int>person;
	queue<int>bag;
	for(int i=1;i<=n;i++){
		bag.push(i);
	}
	for(int i=0;i<n;i++){
		int num;
		cin>>num;
		person.push(num);
	}
	int sum=0;
	double all=0;
	while(bag.size()){
		sum++;
		int a=bag.front();
		int b=person.front();
		if(a==b){
			bag.pop();
			person.pop();
			all+=sum;
		}
		else{
			person.pop();
			person.push(b);
		}
	}
	cout<<sum;
	cout<<' ';
	double ans=all/n;
	printf("%.1f\n",ans);
}
posted on 2026-04-03 17:28  wt_pav  阅读(13)  评论(0)    收藏  举报