CF552 E. Two Teams

Posted bxd123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF552 E. Two Teams相关的知识,希望对你有一定的参考价值。

题意:给出一串n个数   为1-n的乱序

一共有两个教练   教练一的队伍是1队  二是二队

教练一选择 当前队列中剩余人数的最大序号   将其和左边k个人 和右边k个人 变为一队

如此反复直到所有人都分好队伍

 

这题思路很巧妙 

一开始以为要搜索最大值  时间效率肯定很低

但是可以对位置进行映射   避免了寻找最大值(1-n 的排序这一点非常适用)

 

 

一开始的代码: 仔细一想其实缺乏合理性

技术图片
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
#define N 200000+5
int n,k;
int a[N];
int pos[N];
char ans[N];
int le[N];
int ri[N];
int d=1;

int main()
{



    RII(n,k);
    rep(i,1,n)
    {
       RI(a[i]);
       pos[ a[i] ]=i;
       le[i]=i-1;
       ri[i]=i+1;
    }


    CLR(ans,0);
    repp(i,n,1)
    {
        if( ans[ pos[i] ] )continue;
        ans[ pos[i] ]=d+0;

        int L=pos[i],R=pos[i];

        rep(j,1,k)
        {
            L=le[L];
            if(L>=1)ans[L]=d+0;
             R=ri[R];
            if(R<=n)ans[R]=d+0;
        }
        L=le[L];R=ri[R];
        le[R]=L;
        ri[L]=R;

        d=3-d;
    }
    puts(ans+1);



    return 0;
}
View Code

 

wa点:

删边有严格的前后之分!!!!  不然会wa

对比:

wa:

技术图片
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
#define N 200000+5
int n,k;
int a[N];
int pos[N];
char ans[N];
int le[N];
int ri[N];
int d=1;


void del(int x)
{
    ans[x]=d+0;
    int L=le[x];
    int R=ri[x];
    le[R]=L;
    ri[L]=R;
}

int main()
{
    RII(n,k);
    rep(i,1,n)
    {
       RI(a[i]);
       pos[ a[i] ]=i;
       le[i]=i-1;
       ri[i]=i+1;
    }
    repp(i,n,1)
    {
        if( ans[ pos[i] ] )continue;

        del(pos[i]);
        int L=pos[i];
        int R=pos[i];
        rep(j,1,k)
        {
            L=le[L];
            if(L>=1)del(L);
            R=ri[R];
            if(R<=n)del(R);
        }
        d=3-d;
    }
    puts(ans+1);
    return 0;
}
View Code

 

AC:

技术图片
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
#define N 200000+5
int n,k;
int a[N];
int pos[N];
char ans[N];
int le[N];
int ri[N];
int d=1;


void del(int x)
{
    ans[x]=d+0;
    int L=le[x];
    int R=ri[x];
    le[R]=L;
    ri[L]=R;
}

int main()
{



    RII(n,k);
    rep(i,1,n)
    {
       RI(a[i]);
       pos[ a[i] ]=i;
       le[i]=i-1;
       ri[i]=i+1;
    }


    repp(i,n,1)
    {
        if( ans[ pos[i] ] )continue;

        del(pos[i]);
        int L=le[pos[i]];
        int R=ri[pos[i]];
        rep(j,1,k)
        {

            if(L>=1)del(L),L=le[L];

            if(R<=n)del(R),R=ri[R];
        }

        d=3-d;
    }
    puts(ans+1);



    return 0;
}
View Code

 

同时来也会出错!!!!!!

AC:

技术图片
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
#define N 200000+5
int n,k;
int a[N];
int pos[N];
char ans[N];
int le[N];
int ri[N];
int d=1;


void del(int x)
{
    ans[x]=d+0;
    int L=le[x];
    int R=ri[x];
    le[R]=L;
    ri[L]=R;
}

int main()
{
    RII(n,k);
    rep(i,1,n)
    {
       RI(a[i]);
       pos[ a[i] ]=i;
       le[i]=i-1;
       ri[i]=i+1;
    }
    repp(i,n,1)
    {
        if( ans[ pos[i] ] )continue;


        int L=pos[i];
        int R=pos[i];
        rep(j,1,k)
        {
            L=le[L];
            if(L==0)break;
            del(L);
        }
        rep(j,1,k)
        {
            R=ri[R];
            if(R>n)break;
            del(R);
        }


        del(pos[i]);
        d=3-d;
    }
    puts(ans+1);
    return 0;
}
View Code

 

WA:

技术图片
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
#define N 200000+5
int n,k;
int a[N];
int pos[N];
char ans[N];
int le[N];
int ri[N];
int d=1;


void del(int x)
{
    ans[x]=d+0;
    int L=le[x];
    int R=ri[x];
    le[R]=L;
    ri[L]=R;
}

int main()
{
    RII(n,k);
    rep(i,1,n)
    {
       RI(a[i]);
       pos[ a[i] ]=i;
       le[i]=i-1;
       ri[i]=i+1;
    }
    repp(i,n,1)
    {
        if( ans[ pos[i] ] )continue;


        int L=pos[i];
        int R=pos[i];
        rep(j,1,k)
        {
            L=le[L];
            if(L>0)
            del(L);
            R=ri[R];
            if(R<=n)
            del(R);
            
        }
        
        del(pos[i]);
        d=3-d;
    }
    puts(ans+1);
    return 0;
}
View Code

 

这种的话并不是因为同时来!!是因为右边跳到左边了!!!!!!!!!!

AC:

技术图片
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
#define N 200000+5
int n,k;
int a[N];
int pos[N];
char ans[N];
int le[N];
int ri[N];
int d=1;


void del(int x)
{
    ans[x]=d+0;
    int L=le[x];
    int R=ri[x];
    le[R]=L;
    ri[L]=R;
}

int main()
{
    RII(n,k);
    rep(i,1,n)
    {
       RI(a[i]);
       pos[ a[i] ]=i;
       le[i]=i-1;
       ri[i]=i+1;
    }
    ri[n+1]=n+1;
    
    repp(i,n,1)
    {
        if( ans[ pos[i] ] )continue;


        int L=pos[i];
        int R=pos[i];
        rep(j,1,k)
        {
            L=le[L];
            if(L>0)
            del(L);
            R=ri[R];
            if(R<=n)
            del(R);
            
        }
        
        del(pos[i]);
        d=3-d;
    }
    puts(ans+1);
    return 0;
}
View Code

 

然后对上面进行调试也AC了

原来真wa点是ri数组QAQ!!!

技术图片
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
#define N 200000+5
int n,k;
int a[N];
int pos[N];
char ans[N];
int le[N];
int ri[N];
int d=1;


void del(int x)
{
    ans[x]=d+0;
    int L=le[x];
    int R=ri[x];
    le[R]=L;
    ri[L]=R;
}

int main()
{
    RII(n,k);
    rep(i,1,n)
    {
       RI(a[i]);
       pos[ a[i] ]=i;
       le[i]=i-1;
       ri[i]=i+1;
    }
    ri[n+1]=n+1;
    repp(i,n,1)
    {
        if( ans[ pos[i] ] )continue;

        del(pos[i]);
        int L=pos[i];
        int R=pos[i];
        rep(j,1,k)
        {
            L=le[L];
            if(L>=1)del(L);
            R=ri[R];
            if(R<=n)del(R);
        }
        d=3-d;
    }
    puts(ans+1);
    return 0;
}
View Code

 

以上是关于CF552 E. Two Teams的主要内容,如果未能解决你的问题,请参考以下文章

E. Two Teams(线段树+链表)

CF #544 div3 E. K Balanced Teams

Codeforces Round #598 (Div. 3) E. Yet Another Division Into Teams dp

E. DeadLee 思维 贪心 cf官方答案代码详解

timus 1106 Two Teams(二部图)

CF 1114 E. Arithmetic Progression