Problem - 1154E - Codeforces(双向链表+模拟)

Problem - E - Codeforces

题目大意:有 n n n个队员,他们的能力值符合 n n n的排列,现在有两位教练要挑选队员,他们先选择当前队员里能力值最大的,然后选走该名队员左右各 k k k个队员,两个教练依次选取,求每个队员最终属于哪个教练.

解题思路:因为队员的能力值是不重复的,所以找当前能力值最大的,可以直接从 n n n遍历到 1 1 1,维护一下每个被选走的队员.这个题的关键在于,每次把队员选走之后如何去维护剩余的还存在的队员,直观的方法肯定是把已经选择的队员都删除,但是vector的删除复杂度很高.所以这个地方需要借用双向链表来将删除的复杂度降到 O ( 1 ) O(1) O(1).

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define syncfalse ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
const int N = 2e5+5;
bool use[N];
struct node{
    int val, l, r;
}a[N];
int pos[N];
int ans[N];
int main(){
    syncfalse
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    int n, k;
    cin>>n>>k;
    a[0].l=0,a[n+1].r=n+1;         //初始化链表的边界很关键
    for (int i = 1; i <= n; ++i){
        cin>>a[i].val;
        pos[a[i].val]=i;
        a[i].l=i-1,a[i].r=i+1;
    }
    int now = 1;
    for (int i = n; i >= 1; --i){
        if (use[i])continue;
        int tar = pos[i];
        int val = a[tar].val;
        ans[tar]=now;use[val]=true;
        int tem = k;
        int l = tar, r = tar;
        while(tem){
            l=a[l].l;
            if (l==0)break;
            ans[l]=now;
            int val=a[l].val;
            use[val]=true;
            tem--;
        }
        tem=k;
        while(tem){
            r=a[r].r;
            if (r==n+1)break;
            ans[r]=now;
            int val = a[r].val;
            use[val]=true;
            tem--;
        }
        l=a[l].l;
        r=a[r].r;
        a[r].l=l;
        a[l].r=r;
        if (now==1)now=2;
        else now=1;
    }
    for (int i = 1; i <= n; ++i)cout << ans[i];

    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值