题意:
两条平行线,各有n、m个点。要连一些线,两个端点分别是两条平行线上的点,并且不能交叉。在取得最多三角形的情况下,求最小的总的线的长度。
题解:
贪心的策略:从左往右,记l和r为两条平行线第一个没被选的点。计算选l或选r新增的线的长度,选最小的。
不能严谨地证明,但是画个图感觉是挺对的。
//Time:265ms
//Memory:1080KB
//Length:953B
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
#define MAXN 100010
#define EPS 1e-8
int x[2][MAXN];
double cal(int l,int r,int len)
{
len=abs(len);
return sqrt(len*1.0*len+(x[1][r]-x[0][l])*1.0*(x[1][r]-x[0][l]));
}
int main()
{
//freopen("/home/moor/Code/input","r",stdin);
int ncase,n,m,a,b;
scanf("%d",&ncase);
for(int hh=1;hh<=ncase;++hh)
{
printf("Case #%d: ",hh);
scanf("%d%d%d%d",&a,&b,&n,&m);
double ans=0;
for(int i=0;i<n;++i) scanf("%d",&x[0][i]);
for(int i=0;i<m;++i) scanf("%d",&x[1][i]);
ans=cal(0,0,b-a);
for(int l=1,r=1;l<n||r<m;)
{
double t1=1e50,t2=1e50;
if(r!=m) t2=cal(l-1,r,b-a);
if(l!=n) t1=cal(l,r-1,b-a);
if(t1<t2-EPS) ans+=t1,++l;
else ans+=t2,++r;
}
printf("%.2f\n",ans);
}
return 0;
}