NOJ——1627Alex’s Game(II)(尺取)

32 篇文章 0 订阅
5 篇文章 0 订阅
  • [1627] Alex’s Game(II)

  • 时间限制: 2000 ms 内存限制: 65535 K
  • 问题描述
  • Alex likes to play with one and zero as you know .

    Today he gets a sequence which contains n(n<=1e5) integers.Each integer is no nore than 100.now he wants to know what’s the minimun contigous subsequence that their puduct contain no less than k(k<=1e5) zeros in the tail.

  • 输入
  • First are two integers n and k.
    Next contains n lines ,every line contains n integers. 
    All integers are bigger than 0.
  • 输出
  • For each case output the answer if you can find it.
    Else just output “haha”
  • 样例输入
  • 5 1
    2 10 2 5 1
    5 3
    2 10 2 5 1
  • 样例输出
  • 1
    haha
  • 刚开始以为K=0的话就直接输出0,后来发现0的情况要特判:若每一个数都末尾带0,即能被10整除,则输出0,否则只要取那个不是10倍数的数即可,输出1.其他情况用尺取法。

    统计2与5的个数,只有这两个数可以影响末尾0的个数,每一次加上L或减掉R那边的两个统计个数即可。

    代码:

    #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 long long LL;
    #define INF 0x3f3f3f3f
    int two[100010];
    int five[100010];
    int pos[100010];
    inline int conttwo(int n)
    {
    	if(n%2!=0)
    		return 0;
    	else
    	{
    		int ans=0;
    		while (n%2==0)
    		{
    			ans++;
    			n>>=1;
    		}
    		return ans;
    	}
    }
    inline int contfive(int n)
    {
    	if(n%5!=0)
    		return 0;
    	else
    	{
    		int ans=0;
    		while (n%5==0)
    		{
    			ans++;
    			n/=5;
    		}
    		return ans;
    	}
    }
    int main(void)
    {
    	int n,k,dx,ans,i,j,t;
    	while (~scanf("%d%d",&n,&k))
    	{
    		memset(two,0,sizeof(two));
    		memset(five,0,sizeof(five));
    		for (i=1; i<=n; i++)
    		{
    			scanf("%d",&pos[i]);
    			two[i]=conttwo(pos[i]);
    			five[i]=contfive(pos[i]);
    		}
    		if(k<=0)//特判0 
    		{
    			bool flag=0;
    			for (i=1; i<=n; i++)
    			{
    				if(pos[i]%10!=0)
    				{
    					flag=1;
    					break;
    				}
    			}
    			if(flag)
    				printf("%d\n",1);
    			else
    				printf("%d\n",0);
    			continue;
    		}
    		int l=1,r=1,dx=INF;
    		int sum5=0,sum2=0;	
    		while (1)
    		{
    			while (r<=n&&min(sum5,sum2)<k)
    			{
    				sum5+=five[r];
    				sum2+=two[r];
    				r++;
    			}
    			if(min(sum5,sum2)<k)
    				break;
    			dx=min(dx,r-l);
    			sum5-=five[l];
    			sum2-=two[l];
    			l++;
    		}
    		if(dx==INF)
    			printf("haha\n");
    		else
    			printf("%d\n",dx);
    	}
    	return 0;
    }
    

      

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值