P1878玄关求调(有详细注释)
  • 板块题目总版
  • 楼主Wuzke_
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/9/30 11:45
  • 上次更新2024/9/30 16:18:45
查看原帖
P1878玄关求调(有详细注释)
760763
Wuzke_楼主2024/9/30 11:45

题目传送门

代码:

#include<iostream>
#include<queue>
using namespace std;
//priority_queue<pair<相邻男女技术之差的绝对值,pair<左人的下标,右人的下标> > ...(小根堆)... > que; 
priority_queue<pair<int,pair<int,int> >,vector<pair<int,pair<int,int> > >,greater<pair<int,pair<int,int> > > > que;
bool out[4114514];//出列状态 (出列指"出列,跳舞")
int st[4114514];//技术水平 
string s;//性别 
int n,k;//n:人数 k:答案数 
pair<int,int> ans[4114514];//结果 
signed main(){
	cin>>n>>s;
	s=" "+s;
	for(int i=1;i<=n;i++){
		cin>>st[i];
	}
	//以上为输入 
	for(int i=1;i<=n-1;i++){
		if(s[i]!=s[i+1]){
			//若为异性就出列
			que.push(make_pair(abs(st[i]-st[i+1]),make_pair(i,i+1))); 
		}
	}
	while(!que.empty()){
		int l,r;
		//若(技术之差的绝对值最小的)两人都没出列,就添加到答案中 
		if(!out[que.top().second.first] && !out[que.top().second.second]){
			l=que.top().second.first;//左人的下标 
			r=que.top().second.second;//右人的下标 
			k++;
			ans[k].first=l;
			ans[k].second=r;//计入答案 
			out[l]=true;
			out[r]=true;//标记为出列 
			que.pop();//弹出 
		}else{//若两人中存在一人出列 
			que.pop();//则无这种情况,弹出 
			continue;
		}
		//l-1和r+1指的是上面两人出列后,他们两边人的下标
		//若l-1和r+1没有超出范围,并且为异性 
		if(l-1>=1 && r+1<=n && s[l-1]!=s[r+1]){
			//就入队-que 
			que.push(make_pair(abs(st[l-1]-st[r+1]),make_pair(l-1,r+1)));
		}
		
	}
	cout<<k<<endl;//输出答案 
	for(int i=1;i<=k;i++){
		cout<<ans[i].first<<' '<<ans[i].second<<endl;
	}
	return 0;
}
2024/9/30 11:45
加载中...