http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1165
当时做计算机几何的时候也没练过旋转卡壳...对于一类求最小满足条件的区间问题..这种思维是很重要的...
就如同本题...实际上就是要使得从a,b,c中取出的数尽量靠近.. 题目所给的a,b,c已经有序...用三个指针x,y,z来记录当前所在a,b,c的位置..每次在计算完a[x],b[y],c[z]后..将x,y,z都尝试性的往后移一位..找到min(a[x+1],b[y+1,c[z+1])...并真正移动那一位..直到x=an...b=bn....c=cn....这里有个比较好的预处理..就是将a[an+1]=oo b[bn+1]=oo c[cn+1]=oo 这样在做指针移动时..就可以不讨论越界问题了...
Program:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#define oo 2000000000
#define ll long long
#define get(a,b,c) (a-b)*(a-b)+(a-c)*(a-c)+(b-c)*(b-c)
using namespace std;
int n[3],x,y,z;
ll s[3][1000005],t,ans,a,b,c;
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
while (~scanf("%d%d%d",&n[0],&n[1],&n[2]))
{
for (y=0;y<3;y++)
{
for (x=1;x<=n[y];x++) scanf("%lld",&s[y][x]);
s[y][x]=oo;
}
x=y=z=1;
ans=get(s[0][x],s[1][y],s[2][z]);
while (x<=n[0] && y<=n[1] && z<=n[2])
{
t=get(s[0][x],s[1][y],s[2][z]);
a=s[0][x+1]; b=s[1][y+1]; c=s[2][z+1];
if (t<ans) ans=t;
if (a<=b && a<=c) x++; else
if (b<=a && b<=c) y++; else
z++;
}
printf("%lld\n",ans);
}
return 0;
}