Educational Codeforces Round 81 (Rated for Div. 2) B. Infinite Prefixes
SSummerZzz 人气:1题目链接:http://codeforces.com/contest/1295/problem/B
题目:给定由0,1组成的字符串s,长度为n,定义t = sssssss.....一个无限长的字符串。
题目定义一个平衡值x,取t的任意前缀Q,如果Q满足cnt(0,q) - cnt(1,q) = x,即Q中0
的个数-1的个数= x,说明当前的Q是满足题意得一个前缀,问满足x的前缀有多少个,
如果x = ∞,则输出-1.
input
6 10
010010
题目给定说q的长度为28,30,32是平衡前缀。
0100100100100100100100100100
可以看出cnt(0) = 19,cnt(1) = 9,cnt(0)-cnt(1) = 10 = x.
我们也就清楚了题目的意思。
那么我们该怎么优化呢,其实这个题目还是需要一些技巧和规律。
思路:给定了一个串s,有限串q从t中截取无非是x倍的s加上s的一种前缀。
想到这,那我们就应该成s串入手。cnt(0,q) - cnt(1,q)说明是0,1的前缀个数相差。
那么我们先把s的"cnt(0,q) - cnt(1,q)"前缀和求出来tot[1~n],那么我们需要想,什么时候满足-1的情况,即有无穷个平衡前缀,我们可以发现,“有限串q从t中截取无非是x倍的s加上s的一种前缀”,如果tot[n] != 0,那么关于q的"cnt(0,q) - cnt(1,q)"为 n*tot[n] + tot[now](now是s一种前缀的最后一位),这样不断的积累,一定不会得出无限前缀的答案,那如果tot[0]的时候呢,我们发现关于q的"cnt(0,q) - cnt(1,q)"为 n*tot[n] + tot[now] -> n*0+tot[now],说明q可以有不同长度的无限个tot[now],如果tot[now] = x,那就满足无限前缀了。
有限前缀从关于q的"cnt(0,q) - cnt(1,q)"为 n*tot[n] + tot[now]可以很好求出:
m*tot[n]+tot[now] = x,就是一种平衡前缀了。我的基本思想是这样,别的还请思考或者参考代码。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <string> 5 #include <cstring> 6 using namespace std; 7 8 int tot[101000]; 9 string str; 10 int l,x; 11 12 void show(){ 13 for(int i = 1;i <= l; ++i){ 14 cout << tot[i] << ' '; 15 }cout << endl; 16 } 17 18 int main(){ 19 20 21 int T; 22 cin >> T; 23 while(T--){ 24 cin >> l >> x >> str; 25 //s的"cnt(0,q) - cnt(1,q)"前缀和求出来tot[1~n] 26 for(int i = 0; i < l; ++i){ 27 if(str[i] == '0') tot[i+1] = tot[i] +1; 28 else tot[i+1] = tot[i] -1; 29 } 30 //show(); 31 int ans = 0; 32 if(x == 0) ans = 1;//这是一个细节,空串也是一种情况, 33 //那么cnt(0,q) - cnt(1,q) = 0 34 if(tot[l] == 0){ 35 for(int i = 1; i <= l; ++i){ 36 if(tot[i] == x){ 37 ans = -1; break;//无穷 38 } 39 } 40 } 41 else{ 42 int v,mod; 43 for(int i = 1; i <= l; ++i){ 44 //这里有个细节问题 可能 x-tot[i] >0 tot[l] <0 45 //虽然可能mod = 0,可是v其实就是几个s,mod就是s的前缀 46 //那么v不能是负数 比如 3/-1 = -3 ...... 0 47 int v = (x-tot[i])/tot[l]; //整数 48 int mod = (x-tot[i])%tot[l]; //余数 49 if(!mod && v >= 0) 50 ++ans; 51 } 52 } 53 //cout << "--------------------||||" <<ans << endl; 54 cout << ans << endl; 55 } 56 57 return 0; 58 }
加载全部内容