codeforces 551C

题意很简单,,话说我先看的这题,,,,感觉很简单才自信敲A,,,结果。。。呵了个呵。。。。


就是有几个学生,,,要么往前走一步,,,要么搬走一个箱子,,问最少时间。。。。


开始想的是大家一起往前走,,,,,一起搬,,,没事干的往前继续走,,,,,,样例真不够意思全过了。。。。然后就卡了。。。。其实随便一组数据都会错。。。。

比如 4 4 3 4 2 4之类的吧,,也记不住了当时否定了自己就去睡觉了。。。。因为有的时候一个人留在一个地方一直搬箱子,,,,比他走一步搬一步明显搬得要多得多,,,所以中心思想就来了——我们要让最少的人往后走(当然了人比箱子多那没说的了。。。。。)

恩,,,,这么想就简单多了。。。。。。但是怎么实现这个想法呢?我认为比较简单的就是枚举每一秒可能的情况,,,,,然后看看行不行,,,,,一秒一秒加,,,

但是写到这里其实还不是很会(代码能力渣渣渣!),,而且可能会超时(test 8就超时了!!!!)。。。。。。。网上比较流行的方法(什么时候才能不找题解。。哎)就是用二分。。。。这里用一下吧。。。。。。


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include<bits/stdc++.h>

using namespace std;

#define MAXN 100010
#define LL long long

int n, m;
LL stone[MAXN];
LL tmp[MAXN];

int check(LL time)
{

    for(int i = 1; i <= n; i++)
        tmp[i] = stone[i];

    int cnt = n;
    for( int i = 0; i < m; i++)
    {
         while(cnt >= 1 && tmp[cnt] == 0) cnt--;
         if(cnt == 0) return 1;

         LL tot_t = cnt;
         if(tot_t > time) return 0;  //剩下的点比时间还多那还扯个屁!

         while(cnt >= 1 && tmp[cnt] + tot_t <= time)  //可以把这一步的箱子取完。。。
         {
             tot_t += tmp[cnt];  //记录已经走了多长时间
             tmp[cnt] = 0;  //这步的为0
             cnt--;          //到前一步的(往前走不算步数!!)
         }
        if(cnt == 0) return 1;  //如果到0了就是可以成功
        tmp[cnt] -= (time - tot_t);  //没到0就下一个人来,,这个人所对应的点拿走能动的步数的箱子。。。
    }
    return 0;
}

int main()
{
    while(scanf("%d %d",&n, &m) != EOF)
    {
        LL l = 0, r = 0;
        for(int i = 1; i <= n; i++)
        {
            scanf("%lld",&stone[i]);
            r += stone[i];
        }
         r += n;
         while(l < r)
         {
             LL mid = (l + r) >> 1;
             if(check(mid))  //中间那个点符合
                 r = mid;
             else            //中间那个点不够
                l = mid + 1;
         }
         printf("%lld\n",r);
    }
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值