码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces 551C(集训比赛2B_C题)解题报告

时间:2018-01-27 11:30:50      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:string   位置   cto   +=   scanf   oid   scan   最小   set   

题目链接:http://codeforces.com/problemset/problem/551/C

---------------------------------------------------------------------------------

题意:有n个地点,每个地点有箱子,然后有一定人数,每个人从第i个位置移动到第i+1的位置花费1S,每个人移动一个箱子花费1S,要求把所有箱子全部移除花费的最小时间是多少

思路:二分+贪心的思想,每次对一名学生进行判断。对所求时间进行二分,先让学生到达最远的地方,然后剩下的时间就是用来搬箱子的时间,当学生都用完后,观察是否还有箱子没被搬。通过这种情况调整上下界。

代码:

技术分享图片
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
int n;int m;
const int MAXN =1e5+10;
ll a[MAXN];
int far =0;
ll sum;

int jud(ll mid){
    int man =0;
    ll s=0;
    for(int i=1;i<=far;i++){
        s+=a[i];
        while(s+i>=mid){
            s-=mid-i;
            man++;
        }
    }
    if(s>0) man++;
    //printf("man:%d\n",man);
    if(man>m)    return 1;
    else    return 0;
    
}

ll proce(){
    ll left =far+1;
    ll right =far+sum;
    ll mid =(left+right)/2;
    while(right>=left){
        mid =(left+right)/2;
        //printf("left:%d right:%d mid:%d\n",left,right,mid);
        if(jud(mid)){
            left =mid+1;
        }else{
            right =mid-1;            
        }
    }
    return left;
}

int main(void){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        if(a[i]!=0)    far =i;
        sum+=a[i];
    }
    ll ans = proce();
    printf("%lld\n",ans);
    return 0;

}
View Code

 

CodeForces 551C(集训比赛2B_C题)解题报告

标签:string   位置   cto   +=   scanf   oid   scan   最小   set   

原文地址:https://www.cnblogs.com/caomingpei/p/8362053.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!