Codeforces Round #552 (Div. 3)E. Two Teams【模拟】

思路:题意是两个教练每次挑选一个最高的队员,然后可以挑选左右两边连续的k个人,两个教练依次挑选,问最后每个人属于哪个队伍。

暴力是会超时的,应该用链表模拟来写,我是模拟来写的,每次挑剩余中最高那个,然后找左右两边的人,并且更新一下端点情况,记录端点在取完人后新的邻接点的下标。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5 + 10;
int vis[maxn];
struct node
{
    int val;
    int l, i, r;
    bool operator < (const node &s) const
    {
        return val > s.val;
    }
}a[maxn];
map<int, int > m;

int main()
{
    int n, k, x;
    scanf("%d%d", &n, &k);
    for(int i = 1; i <= n; ++i)
    {
        scanf("%d", &a[i].val);
        a[i].i = i;
        a[i].l = i - 1;
        a[i].r = i + 1;
    }
    sort(a + 1, a + n + 1);
    for(int i = 1; i <= n; ++i)
        m[a[i].i] = i;
    int cnt = 1;
    memset(vis, 0, sizeof(vis));
    for(int i = 1; i <= n; ++i)
    {
        if(vis[a[i].i]) continue;
        else ++cnt;
        vis[a[i].i] = cnt % 2 + 1;
        int ix, j, res;
        for(j = a[i].r, res = 1; j <= n && !vis[j] && res <= k; j = a[m[j]].r, ++res)
            vis[j] = cnt % 2 + 1;
        for(ix = a[i].l, res = 1; ix >= 1 && !vis[ix] && res <= k; ix = a[m[ix]].l, ++res)
            vis[ix] = cnt % 2 + 1;
        a[m[ix]].r = j;
        a[m[j]].l = ix;
    }
    for(int i = 1; i <= n; ++i)
        cout << vis[i];
    cout << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41785863/article/details/89386257