CF1056C Pick Heroes 题解
FReQuenter · · 题解
思路
分两种情况讨论:
先手:
显然,通过选一对仇敌关系之中的一个,可以确定让交互库选另一个。所以,先选所有仇敌关系中
策略:先选所有仇敌关系中
后手:
如果交互库选了仇敌关系中的一员,那么只能选这个仇敌关系中的另一个;如果交互库没有那么做,那主动权就落到了我们手里:相当于我们是先手。那么只要和先手一样继续做就行了。
策略:如果交互库选了仇敌关系中的一个,则选另一个;否则:先选剩余仇敌关系中
本题数据范围较小,如果要找没有选的最大的 map 等 STL 或一些数据结构维护,是时间复杂度达到
代码
#include<bits/stdc++.h>
#define fi first
#define se second
#define endl endl<<endl
using namespace std;
int n,m,t,p[2005];
pair<int,int> dis[1005];
bool cho[2005];
struct node{
int num,idx;
node(){}
node(int _num,int _idx){
num=_num;
idx=_idx;
}
friend bool operator < (node a,node b){
if(a.num!=b.num) return a.num<b.num;
return a.idx<b.idx;
}
};
int fnd(int x){
for(int i=1;i<=m;i++){
if((dis[i].fi==x&&!cho[dis[i].se])
||(dis[i].se==x&&!cho[dis[i].fi])) return i;
}
return 0;
}//找第一个没有选的
//其实可以用map维护,但是容易写挂(我很懒的
signed main(){
cin>>n>>m;
for(int i=1;i<=n*2;i++) cin>>p[i];
for(int i=1;i<=m;i++) cin>>dis[i].fi>>dis[i].se;
cin>>t;
priority_queue<node> q;
for(int i=1;i<=n*2;i++){
q.push(node(p[i],i));
}
if(t==1){//先手
for(int i=1;i<=m;i++){
if(p[dis[i].fi]<p[dis[i].se]) swap(dis[i].fi,dis[i].se);
cout<<dis[i].fi<<endl;
int x;
cin>>x;
cho[x]=cho[dis[i].fi]=true;
//优先使用仇敌关系
}
while(!q.empty()){
while(!q.empty()&&cho[q.top().idx]) q.pop();
if(q.empty()) break;
cout<<q.top().idx<<endl;
cho[q.top().idx]=true;
int x;
cin>>x;
cho[x]=true;
}//找最大
}
if(t==2){
for(int i=1;i<=n;i++){
int x;
cin>>x;
cho[x]=true;
int tmp=fnd(x);
if(tmp){
if(dis[tmp].fi==x){
cho[dis[tmp].se]=true;
cout<<dis[tmp].se<<endl;
}
else{
cho[dis[tmp].fi]=true;
cout<<dis[tmp].fi<<endl;
}
//如果是仇敌关系中的一员
}
else{
bool chod=false;
for(int i=1;i<=m;i++){
if(!cho[dis[i].fi]&&!cho[dis[i].se]){
chod=true;
if(p[dis[i].fi]<p[dis[i].se]) swap(dis[i].fi,dis[i].se);
cout<<dis[i].fi<<endl;
cho[dis[i].fi]=true;
break;
//如果还有仇敌关系
}
}
if(!chod){
while(!q.empty()&&cho[q.top().idx]) q.pop();
cout<<q.top().idx<<endl;
cho[q.top().idx]=true;
//没有了仇敌关系,找最大
}
}
}
}
return 0;
}