題目連接:http://codeforces.com/contest/1295/problem/Bios
題目:給定由0,1組成的字符串s,長度爲n,定義t = sssssss.....一個無限長的字符串。優化
題目定義一個平衡值x,取t的任意前綴Q,若是Q知足cnt(0,q) - cnt(1,q) = x,即Q中0spa
的個數-1的個數= x,說明當前的Q是知足題意得一個前綴,問知足x的前綴有多少個,code
若是x = ∞,則輸出-1.blog
input ci
6 10字符串
010010get
題目給定說q的長度爲28,30,32是平衡前綴。input
0100100100100100100100100100string
能夠看出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)"爲 m*tot[n] + tot[now](now是s一種前綴的最後一位),這樣不斷的積累,必定不會得出無限前綴的答案,那若是tot[0]的時候呢,咱們發現關於q的"cnt(0,q) - cnt(1,q)"爲 m*tot[n] + tot[now] -> m*0+tot[now],說明q能夠有不一樣長度的無限個tot[now],若是tot[now] = x,那就知足無限前綴了。
有限前綴從關於q的"cnt(0,q) - cnt(1,q)"爲 m*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 }