题目链接:点击打开链接
题目大意:
如果给定区间内的串中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;
}