Codeforces Round #352 (Div. 2)C. Recycling Bottles

链接:http://codeforces.com/contest/672/problem/C

题意:给定两个人的位置x1,y1,x2,y2和垃圾桶在的位置x,y,再给n个垃圾的位置,每次一个人只能携带一个垃圾,求将所有垃圾送入垃圾桶要走的最短距离。

分析:这个题目的情况太多太杂,导致终测后通过人数从800+人变成了300+人。其实这个题目情况复杂是因为跟垃圾的位置和人的位置的综合原因造成的,如果真的将人去讨论的话会花费大量的时间而麻烦,我们应该学会从多个方面求解问题。我们直接分析3中情况:1:只有a走动。2:只有b走动。3:a,b都走动。然后取最小就行了。

代码:

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#include<math.h>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int N=100010;
const int MAX=1000000100;
const int mod=100000000;
const int MOD1=1000000007;
const int MOD2=1000000009;
const double EPS=0.00000001;
typedef long long ll;
const ll MOD=1000000007;
const int INF=1000000010;
typedef double db;
typedef long double ldb;
typedef unsigned long long ull;
db x[N],y[N];
struct node {
    int u;
    db d;
    node(){}
    node(int u,db d):u(u),d(d){}
    bool operator < (const node a) const{
        return d>a.d;
    }
}a[N],b[N];
db ddis(db x1,db y1,db x2,db y2) {
    db x=x1-x2,y=y1-y2;
    return sqrt(x*x+y*y);
}
int main()
{
    int i,n;
    db xa,xb,ya,yb,X,Y;
    db ans=0,ans1,ans2,ans3;
    scanf("%lf%lf%lf%lf%lf%lf", &xa, &ya, &xb, &yb, &X, &Y);
    scanf("%d", &n);
    for (i=1;i<=n;i++) scanf("%lf%lf", &x[i], &y[i]);
    for (i=1;i<=n;i++) a[i]=node(i,ddis(x[i],y[i],X,Y)-ddis(x[i],y[i],xa,ya));
    for (i=1;i<=n;i++) b[i]=node(i,ddis(x[i],y[i],X,Y)-ddis(x[i],y[i],xb,yb));
    sort(a+1,a+n+1);
    sort(b+1,b+n+1);
    for (i=1;i<=n;i++) ans+=2.0*ddis(X,Y,x[i],y[i]);
    ans1=min(ans-a[1].d,ans+ddis(xa,ya,X,Y));
    ans2=min(ans-b[1].d,ans+ddis(xb,yb,X,Y));
    if (a[1].u==b[1].u) {
        if (a[1].d+b[2].d>=a[2].d+b[1].d) ans3=ans-a[1].d-b[2].d;
        else ans3=ans-a[2].d-b[1].d;
    } else {
        ans3=ans-a[1].d-b[1].d;
    }
    printf("%.10f\n", min(ans1,min(ans2,ans3)));
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值