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


    题目链接: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)"为 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 }
  • 相关阅读:
    知识的本质
    福克斯保养注意事项及驾驶技巧
    转 网络编程
    Linux系统下安装 apache2.4的过程
    代码静态检查工具PCLint运用实践
    gcc编译系统
    量子计算机:决胜21世纪的利器
    关于ETL工具、方案的认识
    《HTTP: The Definitive Guide》读书笔记
    ArrayList(转用法)
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/12246829.html
Copyright © 2020-2023  润新知