Codeforces Round #552 (Div. 3) E. Two Teams 模拟链表


E. Two Teams

题意:两个教练要从 n 个学生中选择队员,第一行输入 n, k,代表学生的数量,和队员选择的范围,第二行输入每个学生的代码技能(1-n且各不相同),每个教练从未属于任何队伍的学生中,先定位代码技能最高的学生,然后将这名学生以及他左边k个学生,右边k个学生归队,第一个教练先开始,输出n个数,1代表归于第一个教练的队伍,2代表归为第二个教练的队伍。


思路(模拟链表):由题意可知,当学生归队之后相当于从未归队学生中删除,会影响到下一个定位最大值的k范围的选择,我们可以将未归队的学生当作一条链表,每次教练的选择之后,将这些归队的学生从链表中删除,用数组模拟这个过程即可。这样想是因为链表的特点-插入删除比较方便快捷


AC代码:

#include
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define show(x) cout< iip;
typedef pair llp;
const int MAXN = 200005;
const int INF = 0x3f3f3f3f;
const int MOD = 998244353;

int i, j, n, k, flag[MAXN] = {0}, zt = 1, t, L[MAXN], R[MAXN], cnt[MAXN] = {0};
iip a[MAXN];

int main()
{
    cin>>n>>k;
    for(i = 1; i <= n; i++) {
        cin>>a[i].first;
        a[i].second = i;
        L[i] = i-1;
        R[i] = i+1;
    }
    sort(a+1, a+n+1, greater());
    for(i = 1; i <= n; i++) {
        int index = a[i].second;
        if(flag[index]) continue;
        flag[index] = zt;
        int l = L[index];
        t = k;
        while(t-- && l > 0){
            flag[l] = zt;
            l = L[l];
        }
        int r = R[index];
        t = k;
        while(t-- && r <= n){
            flag[r] = zt;
            r = R[r];
        }
        zt = (zt == 1 ? 2 : 1);
        R[l] = r;
        L[r] = l;
    }
    for(i = 1; i <= n; i++) {
        cout<

你可能感兴趣的:(Codeforces Round #552 (Div. 3) E. Two Teams 模拟链表)