因为喜欢,所以坚持
本来也是觉得脑子不清晰,但是不然,就是想不到!CF题目都对一些基本知识考查得十分滴灵活。。。。。
缕清思路:
题意先给个字符串s,里面都是1或0,一个串的前缀,在题目中也给出了,字符串t的定义是无数个s拼接起来,现在给定n为字符串s长度以及x让求有多少个t的前缀满足在前缀中0的个数-1的个数等于x,若x无限多个,那么输出-1
那么思考一下,这样的题目肯定得对x和序列中0的个数-1的个数进行判断,分类要做好!但是也不能分太多,别把自己分迷了!跟没说一样。
利用前缀和记录当前位置0的个数-1的个数为多少,然后看代码吧。主要代码借鉴https://me.csdn.net/qq_43734635这位大佬
#include <cstdio>
#include <iostream>
#include <cstring>
#include <sstream>
#include <algorithm>
#include <stack>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
typedef long long LL;
int dis[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
const int maxn = 100000 + 10;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
char s[maxn];
int sum[maxn]; // 记录当前位置0的个数-1的个数 是多少
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
// ios::sync_with_stdio(0);
// cin.tie(0);
// cout.tie(0);
int T;
int n, x;
cin >> T;
while (T--)
{
cin >> n >> x;
int ans = 0;
if (x == 0)
ans++; // 如果为 x 为 0 那么空串铁定满足
scanf("%s", s + 1); // 从下标1 开始放字符
for (int i = 1; i <= n; i++)
{
if (s[i] == '0')
sum[i] = sum[i - 1] + 1;
else
sum[i] = sum[i - 1] - 1;
}
int all = sum[n]; // 这一个周期的增量
if (all == 0)
{
if (x == 0) // 一个周期至少一个 无穷
printf("-1\n");
else
{
for (int i = 1; i <= n; i++)
{
if (sum[i] == x)
ans++;
}
if (ans)
printf("-1\n"); // 一个周期至少一个 无穷
else
printf("0\n"); // 每一个周期内都没有
}
}
else
{
for (int i = 1; i <= n; i++)
{
if (((x - sum[i]) % all == 0) && (x - sum[i]) / all >= 0)
ans++;
// 理解为某个位置的前缀和加上n个周期的贡献为x且贡献次数即之前的周期次数大于等于0次
// 这样就不用考虑正负号的问题了
}
printf("%d\n", ans);
}
}
return 0;
}