数学?(思维,贪心)

链接
题目描述
Tisfy: 这是一道数学题?

给你长度为n的数组a和一个正整数k,问你a有多少个和大于等于k的连续子序列。

输入格式
第一行空格隔开的两个正整数,分别代表数组长度和要大于的数。

第二行n个空格隔开的正整数,代表数组a。

输入格式如下:

n k
a1 a2 … an
其中:

1 ≤ a i ≤ 10^5
1 ≤ n ≤ 10^5
1 ≤ k ≤ 10^10

输出格式
输出一行一个正整数代表数组a aa的 和大于等于k kk的连续子序列 的个数。

输入样例
4 10
6 1 2 7
输出样例
2


分析:最开始肯定不由自觉的想暴力,然后又想前缀和(最多遍历10^10次),显然不行,应该模拟过程不断简化!!!应该从头求和找到第一个大于等于k的子序列,然后标记上位置flag=j,从这个起始点到标记点以及它后面的点子序列和肯定都大于等于k,所以此时已经有(n-flag+1)个子序列了,接着起始点右移一位,如果此时之前的求和减去第一个移走的起点如果还大于等于k就还有(n-flag+1)个子序列符合(注意与起始点关系不大与flag点有关)。如果和<k,就可以从flag点接这加(减少时间),直到和大于等于k再次标记上这点,子序列数量加(n-flag+1);

AC代码:

#include<stdio.h>
#include<string.h>
typedef long long ll ;
ll a[100010],b[100010],ans;
int main()
{
	ll  n,k,i,j,sum,flag;
	scanf("%lld%lld",&n,&k);
	for(i=1;i<=n;i++)
	scanf("%lld",&a[i]);
	ans=0;
	sum=0;
		for(j=1;j<=n;j++)
		{
			sum+=a[j];
			if(sum>=k)
			{
				flag=j;
				ans+=n-j+1;
				break;
			}
		}
	for(i=1;i<=n;i++)
	{
		sum-=a[i];
		if(sum>=k)
		{
			ans+=n-flag+1;
			continue;
		}
		else if(sum<k)
		{
			for(j=flag+1;j<=n;j++)
			{
				sum+=a[j];
				if(sum>=k)
				{
					flag=j;
					ans+=n-j+1;
					break;
				}
			}
		}
		if(sum<k)
	//当加完最后一个还不满足就立即退出,否则再循环sum就乱了 
		break;
	}
	printf("%lld\n",ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值