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; }