动物朋友(河南萌新联赛)

2 篇文章 0 订阅
2 篇文章 0 订阅

题目描述

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网

已知有n个动物朋友排成一排,每个动物朋友都有一个正整数的快乐值,涛涛每次会和连续的动物朋友玩,并且获得这些动物朋友快乐值的和的快乐,而涛涛是个完美主义者,他觉得快乐值刚好是m时候才是快乐的,现在请问有多少种选择方式,使得所选的连续的动物朋友的快乐值刚好为m。

输入描述

输出描述 

 示例1

输入:

11 45
1 4 1 9 19 8 10 8 1 2 3

输出:

思路1(双指针)

题意告诉我们要连续的区间,看示例1,连续的区间为 19,8 ,10,8 

由此我们可以有一个思路就是,连续区间的起点从i(1<=i<=n)开始,依次相加,直到sum==m ,如果sum>m,则将起点往后挪一个,下面是代码。(首先左边界是从最左边开始的,随着右边界的变化,sum也在变化,当sum超过了m,左边界则也变化,有一种双指针的感觉)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5;
int a[N];
signed main(){
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++)
        cin>>a[i];
    int sum=0;
    int res=0;
    for(int i=0,j=0;i<n;i++)
    {
          sum+=a[i];
          while(sum>m) sum-=a[j++];
          res += sum == m;
    }
     cout<<res;
    return 0;
}

下面这个代码是双指针,和下面的前缀和思路一样 

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5;
int a[N];
signed main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
    	cin>>a[i];
    	a[i]+=a[i-1];
	}     
    int res=0;
    int r=1;
    for(int i=1;i<=n;i++)
    {
        while(r<n&&a[r+1]-a[i-1]<=m) r++;
		if(a[r]-a[i-1]==m) res++;
    }
     cout<<res;
    return 0;
}

思路2(二分+前缀和)

首先固定左边界,再想办法固定右边界,右边界越靠右越大,这时可以考虑用前缀和+二分来确定右边界。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5;
int a[N];
signed main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
    	cin>>a[i];
    	a[i]+=a[i-1];
	}     
    int res=0;
    for(int i=1;i<=n;i++)
    {
        int l=i,r=n;
        while(l<r)
        {
        	int mid=(l+r)/2;
        	if(a[mid]-a[i-1]>=m) r=mid;
        	else l=mid+1;
		}
		if(a[l]-a[i-1]==m) res++;  //l是找到的右边界坐标
    }
     cout<<res;
    return 0;
}

拓展

这一题和我之前做的一题的思路是一样的,链接如下:

(12条消息) 【Codeforces Round #799 (Div. 4)】E. Binary Deque_codeforces binary deque_咲月未羽的博客-CSDN博客

算法小白一枚,欢迎大家的交流和指正 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值