zoukankan      html  css  js  c++  java
  • NOJ——1665夜神的思考(YY+组合问题+分类讨论)

    • [1665] 夜神的思考

    • 时间限制: 1000 ms 内存限制: 65535 K
    • 问题描述
    • 最近夜神对二进制很感兴趣,于是他每次看到一串只包含1和0的字符串的时候就会想,这串字符串有多少子串是含有k个1的呢。

      你们能不能快速的解决这个问题。

    • 输入
    • 输入数据包含多组,先输入k ( 0 =< k <= 10^6 ) , 再在接下来的一行输入一串只包含1和0的字符串,字符串的长度不超过10^6.
    • 输出
    • 输出一个整数,这个整数就是这串字符串有多少子串是含有k个1的。
    • 样例输入
    • 1
      1010
      2
      01010
      100
      01010
    • 样例输出
    • 6
      4
      0
    • 提示
    • 第一串字符串中,“1”,“1”,“10”,“01”,“10”,“010”都只含有一个1,所以答案输出6
      第二串字符串中,"101", "0101", "1010", "01010",都含有2个1,所以答案为4。

    做法:total的前n-1个下标记录每一个1的位置,值记录对应左边0的个数(最后第n个位置再多记录一个末尾的0个数)。

    例如:2    00100010  此时k=2,total={1,1,1}代表第一个1左边两个0,第二个1左边三个0,第三个1代表末尾一个0

    然后分类讨论,k=0和k!=0

    ①、k=0比较简单,但是被坑了好多次WA,计算公式是∑(1~当前位置0的个数),例如上题若k=0,那么就是(1+2)+(1+2+3)+(1)=10,此前一直写成2^n-1让我WA了好几次....

    ②、k!=0,那么每次的Sum=(total[l]+1)*(total[r]+1)(其中r-l+1即距离应恒为k)

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<sstream>
    #include<cstring>
    #include<cstdio>
    #include<string>
    #include<deque>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<map>
    using namespace std;
    typedef __int64 LL;
    LL zxc(LL b)
    {
    	LL r=0;
    	for (LL i=1; i<=b; i++)
    	{
    		r=r+i;
    	}
    	return r;
    }
    char cc[1000009];
    LL total[1000009];
    int main (void)
    {
    	LL k,i,j,sum,l,r;
    	while (~scanf("%I64d",&k))
    	{
    		memset(cc,0,sizeof(cc));
    		memset(total,0,sizeof(total));
    		scanf("%s",cc);
    		LL len=strlen(cc);
    		LL ans=0;
    		LL cnt=0;
    		LL sum=0;
    		for (i=0; i<len; i++)
    		{	
    			if(cc[i]=='1')
    			{
    				total[cnt++]=sum;
    				sum=0;
    			}
    			else
    			{
    				sum++;
    			}
    		}
    		total[cnt]=sum;//记录末尾0个数
    		if(k==0)//k==0的情况
    		{
    			for (i=0; i<=cnt; i++)
    			{
    				ans=ans+zxc(total[i]);
    			}
    			printf("%I64d
    ",ans);
    			continue;
    		}
    		l=0;
    		r=k;//定义两个下标
    		for (i=0; r<=cnt; i++)
    		{
    			ans=ans+(total[l]+1)*(total[r]+1);
    			l++;
    			r++;
    		}
    		printf("%I64d
    ",ans);
    	}
    	return 0;
    }
  • 相关阅读:
    Linux内核同步方法
    C++11写轻量级AOP框架
    Typora夜樱主题
    MySQL添加主键和外键
    命题连接词和命题逻辑
    打印一个类全部信息的方法
    getClass()和instanceof以及类的equals方法
    多态
    在构造函数中调用另一个构造函数
    参数传递
  • 原文地址:https://www.cnblogs.com/Blackops/p/5356395.html
Copyright © 2011-2022 走看看