codeforces#352-C - Recycling Bottles-贪心

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


按题意,只需要某个人第一次捡了后,回到原点后,后面的操作的距离 就都是 原点到各点的距离。


所以直接预处理sum=每个点到原点T的距离


然后预处理每个点到a的距离,到b的距离


显然如果要节约时间,就看a的第一步能不能省时间, 找最大的(dis(a,i) -  dis(t,i ))

b同理。

 

所以方案是 只选a

只选b

a,b都选


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;

const double pi=acos(-1.0);
double eps=0.00000001;

int n;
struct node
{
    double x,y;
    int id;
    double val;
    int type;
};
node tt[100005];
node bb[100005];
double xx[100005];
double yy[100005];
bool cmp(node a,node b)
{
    return a.val>b.val;
}
int main()
{

    double  ax,ay,bx,by,tx,ty;

    cin>>ax>>ay>>bx>>by>>tx>>ty;
    cin>>n;
    double x,y;
    double sum=0;
    int ok=0,bok=0;;
    int i,j;
    double sta=sqrt((ax-tx)*(ax-tx)+(ay-ty)*(ay-ty) );
    double stb=sqrt((bx-tx)*(bx-tx)+(by-ty)*(by-ty) );
    for (  i=1; i<=n; i++)
    {
        scanf("%lf%lf",&xx[i],&yy[i]);
        double dis=sqrt((xx[i]-tx)*(xx[i]-tx)+(yy[i]-ty)*(yy[i]-ty));
        double disa=sqrt((xx[i]-ax)*(xx[i]-ax)+(yy[i]-ay)*(yy[i]-ay));
        double disb=sqrt((xx[i]-bx)*(xx[i]-bx)+(yy[i]-by)*(yy[i]-by));
        sum+=2* dis;
        ++ok;
        tt[ok].id=i;
        tt[ok].val=dis- disa;  //节约time
        ++bok;
        bb[bok].id=i;
        bb[bok].val=dis- disb;
    }
    sort(bb+1,bb+1+bok,cmp);
    sort(tt+1,tt+1+ok,cmp);

    int hasreturn=0;
    double ansa=sum-tt[1].val;
    double ansb=sum-bb[1].val;

   double ansc=1e18;
   if (tt[1].id!=bb[1].id)
    ansc=sum-tt[1].val-bb[1].val;
   else
    if (n>1)
    ansc=min(sum-tt[1].val-bb[2].val
    , sum-tt[2].val-bb[1].val);

    printf("%.6lf\n",min(ansa,min(ansc,ansb)));













    return 0;

}


你可能感兴趣的:(codeforces#352-C - Recycling Bottles-贪心)