codeforces#352-C-Recycling Bottles-欲張り
2039 ワード
http://codeforces.com/contest/672/problem/C
タイトル通り、誰かが初めて拾った後、原点に戻った後、後の操作の距離はすべて原点から各点までの距離です.
従ってsum=各点から原点Tまでの距離を直接前処理する
そして、各点からaまでの距離、bまでの距離を前処理する
明らかに時間を節約するには、aの最初のステップが時間を節約できるかどうかを見て、最大の(dis(a,i)- dis(t,i ))
b同理.
だから案はaだけを選ぶ
bのみ選択
a,bはすべて選択する
タイトル通り、誰かが初めて拾った後、原点に戻った後、後の操作の距離はすべて原点から各点までの距離です.
従って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
",min(ansa,min(ansc,ansb)));
return 0;
}