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)"为 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 }

原文地址:https://www.cnblogs.com/SSummerZzz/p/12246829.html

时间: 2024-11-01 12:31:23

Educational Codeforces Round 81 (Rated for Div. 2) B. Infinite Prefixes的相关文章

Educational Codeforces Round 81 (Rated for Div. 2) C. Obtain The String

题目链接:http://codeforces.com/contest/1295/problem/C 题目:给定字符串s,t.  给定一个空串z,需要按照规则把z构造成 string z == string t 的字符串. 规则:有限次从s中任取子序列p,然后进行 string z += string p的操作, s不变. 问能不能构造出p,不能输出-1,可以得话最少几次可以构造出. 大致的想法就是n倍的s字符串串联,然后剔除不必要的字符,就可以得出z, 求最少的倍数n是多少. 主要思路就是用二分

【Educational Codeforces Round 81 (Rated for Div. 2) A】Display The Number

题目链接 [题解] 优先用2个棒子来凑1. 如果为奇数的话,多出来一根用3根来凑个7放在开头 [代码] #include <bits/stdc++.h> using namespace std; int main(){ #ifdef LOCAL_DEFINE freopen("E:\\rush.txt","r",stdin); #endif // LOCAL_DEFINE ios::sync_with_stdio(0),cin.tie(0); int T

Educational Codeforces Round 81 (Rated for Div. 2)

A - Display The Number 题意:给n根火柴,拼出最大的数字. 题解:肯定是数字越多越大,所以尽可能多拿最便宜的2根火柴一个"1",多余的肯定是拿一个"7",由于n>=2,没有特例. void test_case() { int n; scanf("%d", &n); if(n % 2 == 1) { printf("%d", 7); n -= 3; } while(n) { printf(&q

【Educational Codeforces Round 81 (Rated for Div. 2) C】Obtain The String

题目链接 [题解] 显然我们得按顺序获得目标t的每个字符. 对于t[0],t[1],t[2],t[3]... 我们可以在s中找到这么一个子序列. 显然如果找到尾巴还是没有需要的t[i]. 就得从s[0]开始重新开始顺序找. (然后答案递增,因为表示要重新开始加一个子序列了) 但是如果这么直接找的话,复杂度是O(|s||t|)的 是无法接受的. 所以我们可以另外开一个数组 next[i][j] 表示在i-1位置,如果要找下一个紧接着的j的话,需要到哪个位置找.(这个next数组整体往左偏移了下,便

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

题目链接 [题解] 把0看成是1,把1看成是-1 求一个前缀和. pre[i] = pre[i-1]+1 得到delta = pre[n] 显然对于每个位置的值pre[i] 再复制一遍s的话. 下一个s的该位置,也即i+n的前缀和显然为pre[i]+delata 那么无限的情况就很显然了. 即pre[i]==x,而且delata==0. 只要出现一个这种情况,就是无限. 其他情况,每个位置都会朝着目标远离或者毕竟. 看看差值不是不是delta的整数倍就可以了. 如果是的话,说明可以变成x [代码

Educational Codeforces Round 81 (Rated for Div. 2) A Display The Number

A. Display The Number time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output You have a large electronic screen which can display up to 998244353998244353 decimal digits. The digits are displayed

Educational Codeforces Round 81 (Rated for Div. 2)F(线段树)

预处理把左集划分为大小为1~i-1时,把全部元素都移动到右集的代价,记作sum[i]. 然后枚举终态时左集的大小,更新把元素i 留在/移动到 左集的代价. 树状数组/线段树处理区间修改/区间查询 1 #define HAVE_STRUCT_TIMESPEC 2 #include<bits/stdc++.h> 3 using namespace std; 4 #define ll long long 5 const int N=2e5+7; 6 struct Tree{ 7 ll minn,la

Educational Codeforces Round 77 (Rated for Div. 2) C. Infinite Fence

C. Infinite Fence 题目大意:给板子涂色,首先板子是顺序的,然后可以涂两种颜色,如果是r的倍数涂成红色,是b的倍数涂成蓝色, 连续的k个相同的颜色则不能完成任务,能完成任务则输出OBEY,否则输出REBEL 首先我们可以求b,r的gcd d=gcd(b,r) 然后b/=d,r/=d 然后让r<b  if(r>b) swap(b,r) 然后如果要连续k个板子颜色涂成r,则要占的长度是 len = r*(k-1)+1 如果这个长度len>b 则可以完成,否则不可以完成 这个原

Educational Codeforces Round 69 (Rated for Div. 2) B - Pillars

Educational Codeforces Round 69 (Rated for Div. 2) B - Pillars There are n pillars aligned in a row and numbered from 1 to n. Initially each pillar contains exactly one disk. The i-th pillar contains a disk having radius ai. You can move these disks