[codeforces 1295B] Infinite Prefixes 题目读起来有些费劲+周期性+特判+(%0+%负数+%正数)的讨论+比赛做出不易
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址https://codeforces.com/contest/1295/problem/B
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
B - Infinite Prefixes | GNU C++11 | Accepted | 31 ms | 700 KB |
//周期性+特判
//分类讨论,cnt[n]==0,cnt[n]<0,cnt[n]>0 因涉及%cnt[n]
//知道了做法,还有易卡壳的情况
//-1的判定。if(x==cnt[i]){//只能想到x==cnt[n];x==cnt[i]确实想不到,这点最难
//样例解释如下
/*
6 10
010010
3
010010|010010|010010|010010|010010
长度为30,cnt0=4*5=20,cnt1=2*5=10,cnt0-cnt1=10;
010010|010010|010010|010010|0100
长度为28,cnt0=4*4+3=19,cnt1=2*4+1=9,cnt0-cnt1=10;
010010|010010|010010|010010|010010|01
长度为32,cnt0=4*5+1=21,cnt1=2*5+1=11,cnt0-cnt1=10;
5 3
10101
0
10101,因cnt0<=cnt1,故找不到,答案为0
1 0
0
1
空 cnt0=0,cnt1=0,cnt0-cnt1==0,故能找到1个.The empty prefix is a valid prefix of t.
2 0
01
-1
010101... cnt0==cnt1,故cnt0-cnt2==0
*/
较难过的测试数据如下
Input1:
1
3 0
011
Output1:
3
Input2:
1
11 3
00000111111
Output2:
5
#include <stdio.h>
#define maxn 100010
int n,x,cnt1[maxn],cnt[maxn];//cnt1[]统计1的个数,i-cnt1[]统计0的个数,cnt[]统计差值
char s[maxn];
int main(){
int t,i,tot;
scanf("%d",&t);
while(t--){//%cnt[n],故需分cnt[n]==0,cnt[n]<0,cnt[n]>0讨论。
scanf("%d%d%s",&n,&x,s+1);
for(i=1;i<=n;i++)cnt1[i]=cnt[i]=0;
for(i=1;i<=n;i++)cnt1[i]=cnt1[i-1]+s[i]-'0';
if(x<0){
x=-x;
for(i=1;i<=n;i++)cnt[i]=cnt1[i]-(i-cnt1[i]);//1-0的个数
}else
for(i=1;i<=n;i++)cnt[i]=(i-cnt1[i])-cnt1[i];//0-1的个数
if(cnt[n]==0){
for(i=1;i<=n;i++)
if(x==cnt[i]){//只能想到x==cnt[n];x==cnt[i]确实想不到,这点最难。
printf("-1\n");
break;
}
if(i==n+1)printf("0\n");
}
else if(cnt[n]<0){
tot=0;
if(x==0)tot++;//空前缀The empty prefix is a valid prefix of t.
for(i=1;i<=n;i++)
if(cnt[i]>=x&&(cnt[i]-x)%cnt[n]==0)tot++;
printf("%d\n",tot);
}
else if(cnt[n]>0){
tot=0;
if(x==0)tot++;//空前缀The empty prefix is a valid prefix of t.
for(i=1;i<=n;i++)
if(x>=cnt[i]&&(x-cnt[i])%cnt[n]==0)tot++;
printf("%d\n",tot);
}
}
return 0;
}