首先将n个点排序,找出排序后的K,然后分情况讨论。
当 k == n+1时,显然是 k->1->n || k->n->1这两种的较小值,因为三角形的两边之和大于第三边。
当1 <= k && k <= n 时:
1 , k -> 1 -> n+1 -> k+1 ->n || k -> n -> n+1 -> k-1 -> 1,当k+1 || k-1 不存在时将对应步骤忽略。
2 , k - > 1 -> n+1 -> n -> k+1 || k ->n -> n+1 -> 1 -> k-1,当k+1 || k-1 不存在时将对应步骤忽略。
3,这是一种比较奇葩的策略,刚开始做时直觉上认为这种情况是不会存在的,可是.....5个WA教做人。
k -> i -> n -> n+1 -> i-1 -> 1 (i < k) || k -> i -> 1 -> n+1 - > i+1 -> n (i > k) 。
可以理解为花费了 abs(site[k]-site[i]) 的代价以更换起点使得总价值最小,智商好捉急。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <ctime>
#include <iomanip>
#pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-6)
#define _LL long long
#define ULL unsigned long long
#define LL __int64
#define INF 0x3f3f3f3f
#define Mod 1000000007
/** I/O Accelerator Interface .. **/
#define g (c=getchar())
#define d isdigit(g)
#define p x=x*10+c-'0'
#define n x=x*10+'0'-c
#define pp l/=10,p
#define nn l/=10,n
template<class T> inline T& RD(T &x)
{
char c;
while(!d);
x=c-'0';
while(d)p;
return x;
}
template<class T> inline T& RDD(T &x)
{
char c;
while(g,c!='-'&&!isdigit(c));
if (c=='-')
{
x='0'-g;
while(d)n;
}
else
{
x=c-'0';
while(d)p;
}
return x;
}
inline double& RF(double &x) //scanf("%lf", &x);
{
char c;
while(g,c!='-'&&c!='.'&&!isdigit(c));
if(c=='-')if(g=='.')
{
x=0;
double l=1;
while(d)nn;
x*=l;
}
else
{
x='0'-c;
while(d)n;
if(c=='.')
{
double l=1;
while(d)nn;
x*=l;
}
}
else if(c=='.')
{
x=0;
double l=1;
while(d)pp;
x*=l;
}
else
{
x=c-'0';
while(d)p;
if(c=='.')
{
double l=1;
while(d)pp;
x*=l;
}
}
return x;
}
#undef nn
#undef pp
#undef n
#undef p
#undef d
#undef g
using namespace std;
LL num[100010];
double Cal(LL x,LL x0,LL y0)
{
return sqrt((x-x0)*(x-x0) + y0*y0);
}
int main()
{
int n,i;
LL x,y,k;
scanf("%d %I64d",&n,&k);
for(i = 1;i <= n; ++i)
scanf("%I64d",&num[i]);
scanf("%I64d %I64d",&x,&y);
if(k == n+1)
{
sort(num+1,num+n+1);
double anw = num[n]-num[1] + min( Cal(num[n],x,y),Cal(num[1],x,y) );
for(i = 2;i < n; ++i)
anw = min(anw,min(num[n]-num[i],num[i]-num[1]) + num[n]-num[1] + Cal(num[i],x,y));
printf("%.10lf\n",anw);
return 0;
}
k = num[k];
sort(num+1,num+n+1);
for(i = 1;i <= n && num[i] != k; ++i)
;
k = i;
double Min = 1000000000;
double tmp;
tmp = num[k]-num[1] + num[n]-num[1];
for(i = 2;i <= n; ++i)
Min = min(Min,tmp + Cal(num[i-1],x,y) + Cal(num[i],x,y) - (num[i]-num[i-1]));
tmp = num[n]-num[k] + num[n]-num[1];
for(i = 2;i <= n; ++i)
Min = min(Min,tmp + Cal(num[i-1],x,y) + Cal(num[i],x,y) - (num[i]-num[i-1]));
tmp = num[n]-num[1];
if(k-1)
{
Min = min(Min,tmp + Cal(num[n],x,y) + Cal(num[k-1],x,y) - (num[k]-num[k-1]));
Min = min(Min,tmp + Cal(num[n],x,y) + Cal(num[1],x,y) - (num[k]-num[k-1]));
}
else
{
Min = min(Min,tmp + Cal(num[n],x,y));
}
if(k+1 <= n)
{
Min = min(Min,tmp + Cal(num[1],x,y) + Cal(num[k+1],x,y) - (num[k+1]-num[k]) );
Min = min(Min,tmp + Cal(num[1],x,y) + Cal(num[n],x,y) - (num[k+1]-num[k]) );
}
else
{
Min = min(Min,tmp + Cal(num[1],x,y));
}
Min = min(Min,num[n]-num[1]+num[k]-num[1] + Cal(num[n],x,y));
Min = min(Min,num[n]-num[1]+num[n]-num[k] + Cal(num[1],x,y));
for(i = k+1;i <= n; ++i)
{
if(i!=n)
{
Min = min(Min,num[i]-num[k]+num[i]-num[1]+Cal(num[1],x,y)+Cal(num[i+1],x,y)+num[n]-num[i+1]);
}
else
{
Min = min(Min,num[i]-num[k]+num[i]-num[1]+Cal(num[1],x,y)+Cal(num[i+1],x,y));
}
}
for(i = k-1;i >= 1; --i)
{
if(i!=1)
{
Min = min(Min,num[k]-num[i]+num[n]-num[i]+Cal(num[n],x,y)+Cal(num[i-1],x,y)+num[i-1]-num[1]);
}
else
{
Min = min(Min,num[k]-num[i]+num[n]-num[i]+Cal(num[n],x,y)+Cal(num[i-1],x,y));
}
}
printf("%.10lf\n",Min);
return 0;
}