zoukankan      html  css  js  c++  java
  • B. Infinite Prefixes

    题意:给定一个01字符串s,t是无限个01字符串s相连,现在,求这个字符串t中有多少个前缀使得这个前缀的0的个数大于1的个数为x。

    分析:对于01字符串的贡献问题,我们可以把01字符串中0替换成1累加到前缀和中,1替换成-1,累加到前缀和中,这样,我们就能得到一个前缀中01字符的相对关系,比如前缀和等于3,说明0的个数比1的个数多3,然后,我们分情况讨论,首先,如果整个字符串s结束了的贡献为0,说明0和1之间的数量是相同的,随着字符串t的增长,如果这个子串中有个位置的前缀和等于x,说明随着字符串s的无限增长,就会有无穷个前缀等于x,如果这个子串中没有一个位置的前缀和等于x,说明随着字符串的增长,不会有字符串的贡献等于x,输出0,然后我们再讨论一个子串的贡献不是0的,我们如何去确定一个前缀和的贡献等于x,如果一个sum[i] + k * sum[n] == x,那么它就是一个符合的位置,那么只要这个k是整数,那么这个前缀和的贡献就是符合的,然后就可以得到(x - sum[i]) % t == 0这个条件,同时,我们还要保证(x - sum[i])和sum[n]同号,因为我们需要x - sum[i] == k * sum[n],k是一个非负的整数,那么sum[n]和x - sum[i]应该是同号的。同时,还有个小细节,就是空串,空串的贡献应该为0,如果我们的x等于0,那么就增加答案。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    const int N = 100005;
    int sum[N];
    
    int main()
    {
    	int t;
    	cin >> t;
    
    	while (t--)
    	{
    		int n, x;
    		cin >> n >> x;
    
    		char a;
    		for (int i = 1; i <= n; ++i)
    		{
    			cin >> a;
    			if (a == '0')
    				sum[i] = sum[i - 1] + 1;
    			else
    				sum[i] = sum[i - 1] - 1;
    		}
    
    		//第一种情况
    		if (sum[n] == 0)
    		{
    			for (int i = 1; i <= n; ++i)
    			{
    				if (sum[i] == x)
    				{
    					cout << -1 << endl;
    					goto here;
    				}
    			}
    
    			cout << 0 << endl;
    			goto here;
    		}
    		else
    		{
    			int res = 0;
    
    			//空串情况
    			if (x == 0)
    				++res;
    
    			for (int i = 1; i <= n; ++i)
    			{
    				if ((x - sum[i]) % sum[n] == 0 && (x - sum[i]) / sum[n] >= 0)
    					++res;
    			}
    			cout << res << endl;
    		}
    		
    
    		here:;
    	}
    
    
    	return 0;
    }
    
  • 相关阅读:
    常用数列
    sqrt
    树状数组
    hash
    P1102 A-B数对
    codevs 1795 金字塔 2
    P2296 寻找道路
    [USACO16JAN]子共七Subsequences Summing to Sevens
    P3397 地毯
    关于调用&&传址
  • 原文地址:https://www.cnblogs.com/pixel-Teee/p/12247178.html
Copyright © 2011-2022 走看看