CodesForces830A Round #424 Div1A:二分+二部图匹配或者三分乱搞

题意:给出一条直线(1-1e9),直线上有n(<=1000)个人,分别站在peo[i]的位置上,有k(<=2000)个钥匙,分别位于ke[i]的位置上,还有一个办公室位于p。

要求每个人任意拿一把钥匙,并且走到办公室位置,每个钥匙只能被一个人拿走,拿钥匙不花费时间,走一单位长度花费1s时间,求所有人都到达办公室的最短时间。

题解1:所有人都到达办公室的时间=所有人里边到达办公室最耗时的那个人,那么这个题变成了最大值最小,典型的二分题,现在的问题是给定一个maxTime,想一种办法检验是否所有的n个人都可以在小于等于maxTIme的时间内拿走钥匙并到达办公室。其实这是一个匹配问题,把人和钥匙分成两部分图。每个人把所有的钥匙的时间算出来(包括最后走到办公室的时间),然后如果这个时间小于maxTime,就连一条边(边权=1),算这个图的最大匹配等于n就说明可行。这部分代码等后边补出来。

题解2:显然如果把人排序,把钥匙排序,每个人要得到一把钥匙,并且走到办公室,钥匙的分布一定是连续的,可以通过假定n-1把钥匙连续分布,另外一把钥匙单列,那么一定不如n个都连续来的优。可以通过暴力的枚举第一个人拿那个钥匙,也就是nk的复杂度得到答案。另外这个题满足三分性质,可以类比一下之前有个SnakeDown的题目,连接在下边。

Code1:

现在没有

Code2:

#include
using namespace std;
#define MAXN 2005
int peo[MAXN],ke[MAXN];
int k,n,p;
long long ans =0;
long long calc(int startIndex){
    long long deltaAns =0;
    for (int i=0;i=peo[i]&&temp<=p||temp<=peo[i]&&temp>=p){
            long long ans2 = (abs(peo[i]-p));
            deltaAns=max(deltaAns,ans2);
        }else if (peo[i]>=temp&&peo[i]<=p||peo[i]>=p&&peo[i]<=temp){
            long long ans2 = abs(peo[i]-p)+2*abs(temp-peo[i]);
            deltaAns=max(deltaAns,ans2);
        }else{
            long long ans2 = abs(peo[i]-temp)+abs(temp-p);
            deltaAns = max(deltaAns,ans2);
        }
    }
    return deltaAns;
}
int main(){
    cin>>n>>k>>p;
    for (int i=0;i>peo[i];
        ans+=abs(peo[i]-p);
    }
    for (int i=0;i>ke[i];
    }
    sort(peo+0,peo+n);
    sort(ke+0,ke+k);
    long long ll = 0;
    long long  rr = k-n;
    while (rr>ll+2){
        int mid = (rr-ll)/3+ll;
        int mmid = (rr-ll)/3*2+ll;
        long long midAns = calc(mid);
        long long mmidAns = calc(mmid);
//        cout<<"l:"<


你可能感兴趣的:(Codeforces)