USACO 2018 December Contest, Silver T1 Convention

终于到gold了感动QAQ

一场别开生面的牛吃草大会就要在Farmer John的农场举办了!
世界各地的奶牛将会到达当地的机场,前来参会并且吃草。具体地说,有N头奶牛到达了机场(1≤N≤1e5),其中奶牛i在时间ti(0≤ti≤1e9)到达。Farmer John安排了M(1≤M≤1e5)辆大巴来机场接这些奶牛。每辆大巴可以乘坐C头奶牛(1≤C≤N)。Farmer John正在机场等待奶牛们到来,并且准备安排到达的奶牛们乘坐大巴。当最后一头乘坐某辆大巴的奶牛到达的时候,这辆大巴就可以发车了。Farmer John想要做一个优秀的主办者,所以并不想让奶牛们在机场等待过长的时间。如果Farmer John合理地协调这些大巴,等待时间最长的奶牛等待的时间的最小值是多少?一头奶牛的等待时间等于她的到达时间与她乘坐的大巴的发车时间之差。
输入保证MC≥N。

↑↑↑官方翻译↑↑↑

求最大的最小,很容易想到要二分答案,事实上就是这样!(我第一反应还以为是今年noip普及组的那个摆渡车。。。还以为要DP结果发现似乎是二分答案)
二分时间的差记作lngst,首先先把来的时间从小到大排个序。我用了其他的三个变量:cnt:当前车上有的牛的数量,ct:当前车的开车时间,cn:已经用了几辆车了。
二分中判断能否上车:能上就上,此时,cnt++;不能上,即cnt==c或t[i]-ct<=lngst,换车,ct=t[i];cnt=1;cn++;   最后若cn>m则lngst太小了,否则可以。

#include<bits/stdc++.h>

using namespace std;

int n,m,c,t[100001];

bool cmp(int a,int b)
{
 return a>b;
}

bool check(int lngst)
{
    int ct=t[1],cn=1,cnt=1;
    for (int i=2;i<=n;++i)
    {
        if (t[i]-ct<=lngst && cnt<c) 
        {
            cnt++;
//   cout<<t[i]<<' '<<cn<<' '<<ct<<endl;
        }
        else
        {
            ct=t[i];
       	    cnt=1;
//   cout<<t[i]<<' '<<cn<<' '<<ct<<endl;
            cn++;
        }
    }
// cout<<cn<<endl<<endl;
    if(cn>m)
  	return false;
    return true;
}

int main()
{
 freopen("convention.in","r",stdin);
 freopen("convention.out","w",stdout);
 cin>>n>>m>>c;
 int l=0,r=1e9;
 for(int i=1;i<=n;i++)
 {
  cin>>t[i];
//  l=(t[i]<l)?t[i]:l;
//  r=(t[i]>r)?t[i]:r;
 }
 r++;
 sort(t+1,t+n+1);
    while (l+1<r)
    {
        int mid=l+r>>1;
        if (check(mid)) r=mid;
        else l=mid;
    }
    if (check(l))
  cout<<l;
    else
  cout<<r;
// fclose(stdin);
// fclose(stdout);
 return 0;
}
原文地址:https://www.cnblogs.com/InedibleKonjac/p/12654962.html