华科网赛 K题

4 篇文章 0 订阅


链接:https://www.nowcoder.com/acm/contest/106/K
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

It’s universally acknowledged that there’re innumerable trees in the campus of HUST.

Now you're going to walk through a large forest. There is a path consisting of N stones winding its way to the other side of the forest. Between every two stones there is a distance. Let d i indicates the distance between the stone i and i+1.Initially you stand at the first stone, and your target is the N-th stone. You must stand in a stone all the time, and you can stride over arbitrary number of stones in one step. If you stepped from the stone i to the stone j, you  stride a span of  (di+di+1+...+dj-1). But there is a limitation. You're so tired that you want to walk through the forest in no more than K steps. And to walk more comfortably, you have to minimize the distance of largest step.

输入描述:

  
  
The first line contains two integer N and K as described above.
Then the next line N-1 positive integer followed, indicating the distance between two adjacent stone .

输出描述:

An integer, the minimum distance of the largest step.
示例1

输入

6 3
1 3 2 2 5

输出

5


没想到我这次反应这么灵敏,一看就想到了二分,然后就有思路了,不过就是long long 卡了太长时间。

哎,不过话说回来也只是因为做过类似的题目。


这个题的思路就是不断列举跨步的长度,看它是否满足条件(关键的一点是  这个跨步的长度(也就是我们要的答案)  和 k 有关系 ),你想一下,当你一步能跨无穷大的时候,是不是只用1步就可以走完所以的石头啊,   然后当你一步只能跨1的时候,你是不是要跨很多很多步啊(甚至到不了最后一个石头),就提示到这吧。

二分的题,写起来简单,看出来难啊



#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
int n,k;
typedef long long ll;
const int maxn = 1e5+4;
int a[maxn];

bool check(ll x)
{
    ll total = 0;
    int cnt = 1;
    for( int i = 1 ; i <= n-1 ; i++ )
    {
        if( a[i]>x )
            return false;
        if( total+a[i]<= x )
            total+=a[i];
        else
        {
            total = a[i];
            cnt++;
        }
    }
    if( cnt <= k )
        return true;
    return false;
}
int main()
{

	cin>>n>>k;
    for( int i = 1 ; i<= n-1 ; i++ )
        scanf("%d",&a[i]);
    int t;
    ll l = 0,r = 1e10+1;
    ll m;
    while( l<=r )
    {

        m = (l+r)>>1;
        if( check(m) )
            r = m-1;
        else l = m+1;
    }
    cout<<l<<endl;
    return 0;
}
/*

6 3
10 20 15 18 9

6 2
10 20 15 18 9

6 1
10 20 15 18 9

6 5
10 20 15 18 9

6 4
10 20 15 18 9


*/



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值