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; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮