Educational Codeforces Round 81 (Rated for Div. 2) B. Infinite Prefixes

題目連接: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 }
相關文章
相關標籤/搜索