Codeforces Round #215 (diy.2) C. Sereja and Algorithm

题目链接:点击打开链接


题目大意:

如果给定区间内的串中x、y、z 数量三者中任意两个都要求相等或最多相差1,则puts("YES\n"),否则puts("NO\n");


如果是读入区间以后遍历就超时,我对复杂度所需要的大概时间目前为止都不会判断= =

但是如果在询问前预处理一遍,则OK。


经验积累:

1、这种区间询问的还是先预处理一下才省时~

2、判断三者均分的情况(每次一人给一个,直到分完)

      这个如果每次都判断a==n/3,b==n/3,c==n/3 ||a==n/3+1,b==n/3.。。。(此处省略冗长的判断),那么代码将不简洁也不高效。

      

      所以直接在a、b、c中找到最小的值t,用三者减去t,判断减去后是不是<=1就可以了。


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<queue>
#include<cstring>
#include<string>
#define INF 0x3f3f3f3f

using namespace std;

char s[100010];
int x[100010];
int y[100010];
int z[100010];

void check(int l,int r)
{
    int nx=x[r]-x[l-1];
    int ny=y[r]-y[l-1];
    int nz=z[r]-z[l-1];

    int t=min(min(nx,ny),nz);
    nx=nx-t;
    ny=ny-t;
    nz=nz-t;

    //if(nx<=1 && ny<=1 && nz<=1 || r-l+1<3)
    if(max(max(nx,ny),nz)<=1 || r-l+1<3)
        puts("YES");
    else puts("NO");
}

int main()
{
    int m,a,b;
    while(scanf("%s",s)!=EOF)
    {
        memset(x,0,sizeof(x));
        memset(y,0,sizeof(y));
        memset(z,0,sizeof(z));

        //x[0]=y[0]=z[0]=0;
        for(int i=0;s[i];i++)
        {
            if(s[i]=='x')
                x[i+1]=x[i]+1;
            else  x[i+1]=x[i];

            if(s[i]=='y')
                y[i+1]=y[i]+1;
            else y[i+1]=y[i];

            if(s[i]=='z')
                z[i+1]=z[i]+1;
            else z[i+1]=z[i];
        }
        scanf("%d",&m);
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&a,&b);
            check(a,b);
        }
        memset(s,0,sizeof(s));
    }
    return 0;
}


开始Tle的代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<queue>
#include<cstring>
#include<string>
#define INF 0x3f3f3f3f

using namespace std;

char s[100010];
//char a[6][10]={"zyx","xzy","yxz","xyz","yzx","zxy"};

void check(int l,int r)
{
    if(l==r || r-l==1)
    {
        printf("YES\n");
        return;
    }

    int cnt1=0,cnt2=0,cnt3=0;
    for(int i=l;i<=r;i++)
    {
        if(s[i]=='x') cnt1++;
        else if(s[i]=='y') cnt2++;
        else cnt3++;
    }

    int n=r-l+1;

    //cout<<cnt1<<' '<<cnt2<<' '<<cnt3<<endl;
    //cout<<n<<endl;
    if(n%3==0)
    {
        if(cnt1==n/3 && cnt2==n/3 && cnt3==n/3)
            printf("YES\n");
        else printf("NO\n");
    }

    else if(n%3==1)
    {
        int flag=1,t=cnt1;
        if(t<cnt2)
        {
            t=cnt2;
            flag=2;
        }
        if(cnt3>t)
        {
            t=cnt3;
            flag=3;
        }
        if(t=n/3+1)
        {
            if(flag==1 && cnt2==n/3 && cnt3==n/3)
                printf("YES\n");
            else if(flag==3 && cnt2==n/3 && cnt1==n/3)
                printf("YES\n");
            else if(flag==2 && cnt1==n/3 && cnt3==n/3)
                printf("YES\n");
            else printf("NO\n");
        }
        else printf("NO\n");
    }
    else if(n%3==2)
    {
        int flag=1,t=cnt1;
        if(t>cnt2)
        {
            t=cnt2;
            flag=2;
        }
        if(cnt3<t)
        {
            t=cnt3;
            flag=3;
        }
        if(t=n/3)
        {
            if(flag==1 && cnt2==n/3+1 && cnt3==n/3+1)
                printf("YES\n");
            else if(flag==3 && cnt2==n/3+1 && cnt1==n/3+1)
                printf("YES\n");
            else if(flag==2 && cnt1==n/3+1 && cnt3==n/3+1)
                printf("YES\n");
            else printf("NO\n");
        }
        else printf("NO\n");
    }
}

int main()
{
    int m,a,b;
    while(scanf("%s",s+1)!=EOF)
    {
        //printf("%s\n",s+1);
        scanf("%d",&m);
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&a,&b);
            check(a,b);
        }
        memset(s,0,sizeof(s));
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值