返回顶部

Codeforces Round #552 (Div. 3) E. Two Teams (模拟,优先队列,双向链表)

  • 题意:有\(n\)个队员站成一排,有两个教练分别选人,每次选当前剩余人中的能力值最大的那个以及他两边相邻的\(k\)个人,问最后每个人所在队伍情况.

  • 题解:优先队列模拟,以及双向链表,先用结构体存入每个人的状态,然后全部push到优先队列中,每次将已经分好队的人弹出,然后找当前能力值最大的人分组,至于两边的\(k\)个人,因为我们会对他们也进行分组,所以之后肯定不会再选他们了,所以可以模拟链表,直接让当前能力值最大的人的左边指向\(i-k-1\)即可,右边也是如此,其实也就是链表删除节点的过程,但是要记得在这个过程中对这些点进行分组.还有!!!最最重要的是,不要直接对队列中取出的元素进行修改,没用的,我们可以找到id后对结构体全局变量\(e\)进行修改.

  • 代码:

    struct misaka{
    	int id,val,l,r,t;
    	bool operator < (const misaka & mikoto) const {
    		return val<mikoto.val;
    	}
    }e[N];
    
    
    int n,k;
    int a[N];
    priority_queue<misaka> h;
    
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
        cin>>n>>k;
    
        rep(i,1,n){
        	e[i].id=i;
        	cin>>e[i].val;
        	e[i].l=i-1;
        	e[i].r=i+1;
        	e[i].t=0;
        	h.push(e[i]);
        }
    
        int cur=1;
        e[n].r=0;
    
        while(!h.empty()){
    
        	while(!h.empty() && e[h.top().id].t!=0) h.pop();
        	if(h.empty()) break;
    
        	misaka tmp=h.top();
    
        	e[tmp.id].t=cur;
        	int pos1;
        	int pos2;
        	int now=k;
        	for(pos1=e[tmp.id].l;now-- && pos1;pos1=e[pos1].l) e[pos1].t=cur;
        	now=k;
        	for(pos2=e[tmp.id].r;now-- && pos2;pos2=e[pos2].r) e[pos2].t=cur;
    
        	e[pos2].l=pos1;
        	e[pos1].r=pos2;
    
        	cur=3-cur;
        }
    
        rep(i,1,n) cout<<e[i].t;
     
        return 0;
    }
    
posted @ 2020-11-14 17:38  Rayotaku  阅读(208)  评论(0编辑  收藏  举报