A. Recycling Bottles(坐标距离和转化)
https://codeforces.com/problemset/problem/671/A
题目描述
It was recycling day in Kekoland. To celebrate it Adil and Bera went to Central Perk where they can take bottles from the ground and put them into a recycling bin.
We can think Central Perk as coordinate plane. There are nn bottles on the ground, the ii -th bottle is located at position (x_{i},y_{i})(xi,yi) . Both Adil and Bera can carry only one bottle at once each.
For both Adil and Bera the process looks as follows:
- Choose to stop or to continue to collect bottles.
- If the choice was to continue then choose some bottle and walk towards it.
- Pick this bottle and walk to the recycling bin.
- Go to step 11 .
Adil and Bera may move independently. They are allowed to pick bottles simultaneously, all bottles may be picked by any of the two, it's allowed that one of them stays still while the other one continues to pick bottles.
They want to organize the process such that the total distance they walk (the sum of distance walked by Adil and distance walked by Bera) is minimum possible. Of course, at the end all bottles should lie in the recycling bin.
输入格式
First line of the input contains six integers a_{x}ax , a_{y}ay , b_{x}bx , b_{y}by , t_{x}tx and t_{y}ty ( 0<=a_{x},a_{y},b_{x},b_{y},t_{x},t_{y}<=10^{9}0<=ax,ay,bx,by,tx,ty<=109 ) — initial positions of Adil, Bera and recycling bin respectively.
The second line contains a single integer nn ( 1<=n<=1000001<=n<=100000 ) — the number of bottles on the ground.
Then follow nn lines, each of them contains two integers x_{i}xi and y_{i}yi ( 0<=x_{i},y_{i}<=10^{9}0<=xi,yi<=109 ) — position of the ii -th bottle.
It's guaranteed that positions of Adil, Bera, recycling bin and all bottles are distinct.
输出格式
Print one real number — the minimum possible total distance Adil and Bera need to walk in order to put all bottles into recycling bin. Your answer will be considered correct if its absolute or relative error does not exceed 10^{-6}10−6 .
Namely: let's assume that your answer is aa , and the answer of the jury is bb . The checker program will consider your answer correct if .
题意翻译
Adil和Bera两个人在公园捡地上的瓶子放到垃圾桶里,公园可以视为一个二维平面,地上有nn个瓶子,第ii个瓶子的位置是(x_i, y_i)(xi,yi).Adil和Bera每个人一次只能携带一个瓶子
他们按照如下步骤捡瓶子:
1:决定停下或者继续捡瓶子
2:如果决定继续捡瓶子,则走向一个地上的瓶子
3:捡起这个瓶子,走向垃圾桶
4:回到步骤1
你可以任意安排Adil和Bera怎么捡瓶子(两个人捡的瓶子可能不一样多,甚至可能有一个人在原地没有捡瓶子),需要将所有的瓶子都捡到垃圾桶里,要求两人走的路程之和最小
输入:
第一行六个数a_x, a_y, b_x, b_y, t_x, t_y(0<=a_x, a_y, b_x, b_y, t_x, t_y<=10^9)ax,ay,bx,by,tx,ty(0<=ax,ay,bx,by,tx,ty<=109),依次为Adil, Bera, 垃圾桶的初始坐标
第二行一个数n(1<=n<=10^5)n(1<=n<=105),表示瓶子的个数
接下来nn行,每行两个数x_i, y_i(0<=x_i, y_i<=10^9)xi,yi(0<=xi,yi<=109),表示第ii个瓶子的坐标 输出一个数,表示最小路程和(与答案的绝对误差或相对误差在10^-610−6以内即被视为正确)
输入输出样例
输入 #1复制
3 1 1 2 0 0 3 1 1 2 1 2 3
输出 #1复制
11.084259940083
输入 #2复制
5 0 4 2 2 0 5 5 2 3 0 5 5 3 5 3 3
输出 #2复制
33.121375178000
说明/提示
Consider the first sample.
Adil will use the following path: .
Bera will use the following path: .
Adil's path will be units long, while Bera's path will be units long.
思路:蛮有意思的一题。
先统计出所有瓶子到垃圾桶的距离。dis[i]。记录一个sum=2*dis[i]
统计出所有瓶子到A的距离Adis[i],所有瓶子到B的距离Bdis[i]
如果只让A去捡,枚举捡的起点。ans=min(ans,sum+Adis[i]-dis[i]);
如果只让B去捡,枚举捡的起点。ans=min(ans,sum+Bdis[i]-dis[i]);
A和B同时捡,假如A捡i,B捡j,那么式子是sum+Adis(A,i)+Bdis(B,j)-tdis(i,t)-tdis(j,t);
转化一下,预处理Adis(A,i)-tdis(i,t)和Bdis(B,j)-tdis(j,t);
有i和j相等的情况,记录一下每个瓶子的标号就好了。
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+100;
typedef long long LL;
LL n;
double dis[maxn];//每个瓶子到垃圾桶的距离
double ax,ay,bx,by,tx,ty;
double Adis[maxn];//A到每个瓶子的距离
double Bdis[maxn];//B到每个瓶子的距离
struct node{
double x,y;
}nodes[maxn];
struct cnt{
double distance;LL id;
}Acnts[maxn],Bcnts[maxn];
bool cmp(cnt Q,cnt R)
{
if(Q.distance==R.distance) return Q.id<R.id;
return Q.distance<R.distance;
}
int main(void)
{
//cin.tie(0);std::ios::sync_with_stdio(false);
cin>>ax>>ay>>bx>>by>>tx>>ty;
cin>>n;
for(LL i=1;i<=n;i++){
cin>>nodes[i].x>>nodes[i].y;
}
for(LL i=1;i<=n;i++){
dis[i]=sqrt( (1.0*tx-nodes[i].x)*(tx-nodes[i].x)+(1.0*ty-nodes[i].y)*(ty-nodes[i].y) );
Adis[i]=sqrt( (1.0*ax-nodes[i].x)*(ax-nodes[i].x)+(1.0*ay-nodes[i].y)*(ay-nodes[i].y));
Bdis[i]=sqrt( (1.0*bx-nodes[i].x)*(bx-nodes[i].x)+(1.0*by-nodes[i].y)*(by-nodes[i].y));
Acnts[i].id=i;Acnts[i].distance=1.0*Adis[i]-1.0*dis[i];
Bcnts[i].id=i;Bcnts[i].distance=1.0*Bdis[i]-1.0*dis[i];
}
double sum=0;
for(LL i=1;i<=n;i++) sum+=dis[i]*2.0;
double ans=1e17;//注意开大..0x3f3f3f3f不够,wa8
//所有都被A捡的
for(LL i=1;i<=n;i++){
ans=min(ans,sum+Adis[i]-dis[i]);
}
//所有都被B捡的
for(LL i=1;i<=n;i++){
ans=min(ans,sum+Bdis[i]-dis[i]);
}
//A,B混捡
sort(Acnts+1,Acnts+1+n,cmp);sort(Bcnts+1,Bcnts+1+n,cmp);
if(Acnts[1].id==Bcnts[1].id){
ans=min(ans,sum+Acnts[1].distance+Bcnts[2].distance);
ans=min(ans,sum+Acnts[2].distance+Bcnts[1].distance);
}
else{
ans=min(ans,sum+Acnts[1].distance+Bcnts[1].distance);
}
printf("%.12f\n",ans);
return 0;
}