【普及1】大哈爬楼梯 超时求指点

大哈爬楼梯

题目ID:8593

题目描述
大哈有天梦到自己在爬楼梯,一共有n级台阶。然后突发奇想,要是自己的腿长可以变的话其实爬到的高度也不同。比如2,3岁的小孩子,因为腿太短了,所以一级台阶都上不去;如果他有姚明那么长的腿,那可能即便这个台阶高一米,也能跨上去。给出A数组,代表第i级台阶和前一级台阶的高度差。比如
A
1

3
,
A
2

1
A
1

=3,A
2

=1,那此时第2级台阶的高度就是3 + 1 = 4。然后大哈问q次,每次问如果他一步能跨Bi米的高度,那么最高能爬多高?

输入格式
第一行两个整数n,q,分别代表台阶数和询问的数量
第二行n个整数Ai ,代表第i级台阶和前一级的高度差,第1级台阶前就是地面,高度为0。
第三行q个整数Bi ,代表每次的询问

输出格式
一行,对于每次询问回答最高能爬多高。

问题代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,q,a[200005],b[200005],sum[200005];
bool check2(int x,int y)
{
	int last=0;
	for(int i=1;i<=x;i++)
	{
		if(sum[i]-sum[last]<=y)
		{
			last=i;
		}
	}
	if(last==x)
	{
		return true;
	}
	else
	{
		return false;
	}
}
signed check(int x)
{
	int l=0;
	int r=n;
	while(l<r)
	{
		int mid=(l+r+1)/2;
		if(check2(mid,x))
		{
			l=mid;
		}
		else
		{
			r=mid-1;
		}
	}
	return l;
}
signed main(void)
{
	cin.sync_with_stdio(0);
	cin.tie(0);
	cin>>n>>q;
	sum[0]=0;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		sum[i]=sum[i-1]+a[i];
	}
	for(int i=1;i<=q;i++)
	{
		cin>>b[i];
	}
	for(int i=1;i<=q;i++)
	{
		int k=check(b[i]);
		cout<<sum[k]<<" ";
	}
	return 0;
}
2 个赞

格式化一下,用这个 :point_down:
image

2 个赞

@成笑尘 这是二分好吧

2 个赞
#include<bits/stdc++.h>
using namespace std;
long long a[200001],c[200001],d[200001];
long long n,m;
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		c[i]=...;//这层到上一层的距离
		d[i]=...;//这层的最高距离
	}
	for(int i=1;i<=m;i++){
		long long s;
		cin>>s;
		int mid=upper_bound(c+1,c+n+1,s)-c;//二分函数,看不懂可以自己码二分模板(这个函数等于找最后一个小于s的数的位置)
		if(mid==n+1){
			cout<<d[n]<<" ";
		}else{
			cout<<d[mid-1]<<" ";
		}
	}
}
2 个赞

好的,谢谢

2 个赞

请问在写二分的时候有什么需要注意的地方吗?
问什么我写的二分超时了呢?

2 个赞

@成笑尘 二分思路可以改(虽然我没看懂你代码),暴力应该知道,那就可以化简:
题目让你求最多能跨到多少,其实就是看bi最多能到哪:

原台阶:1,3,4,9
差距:2,1,5
b数组:1,2,4,9,10
答案:1,4,4,9,9
现在可以发现,只要bi不小于当前差距就可以走,那就可以二分bi能到哪(应该会了吧)

注意事项老师应该会讲

1 个赞

二分能登上的最高层数呀

2 个赞

这个?

1 个赞

二分模板做过吧?他二分当前值在哪或比它小(大)的位置

1 个赞

这题就是二分模板

1 个赞

啊,我试试,但暴力不会超时吗?

1 个赞

只需要转化一下(二分啥你可以自己定)

1 个赞

会啊
@成笑尘

1 个赞

我之前TLE20

1 个赞

@信友队蔡老师 代码还是超时啊,还是搞不明白啊!

1 个赞

@成笑尘 私下找我

1 个赞

我没看懂你check2在干嘛,如果你是要找有没有比你那个x要大的,为什么不在输入的时候就确保呢?

2 个赞

主要是last怎么和x比较(我是没看出来)

1 个赞

吧q个询问的Bi从小到大排序(记得记录他们原来的位置,开结构体),以O(n+q)时间遍历,每次检验台阶高度差,不行就存答案,换下一个Bi继续,因为下一个Bi一定能走过前面的

2 个赞