题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17267
【思路】
凸包+旋转卡壳
求出凸包,用旋转卡壳算出凸包的直径即可。
【代码】
1 #include<cstdio> 2 #include<vector> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 struct Pt { 8 int x,y; 9 Pt(int x=0,int y=0):x(x),y(y) {}; 10 }; 11 typedef Pt vec; 12 13 vec operator - (Pt A,Pt B) { return vec(A.x-B.x,A.y-B.y); } 14 bool operator < (const Pt& a,const Pt& b) { 15 return a.x<b.x || (a.x==b.x && a.y<b.y); 16 } 17 bool operator == (const Pt& a,const Pt& b) { 18 return a.x==b.x && a.y==b.y; 19 } 20 21 int Dot(vec A,vec B) { return A.x*B.x+A.y+B.y; } 22 int cross(vec A,vec B) { return A.x*B.y-A.y*B.x; } 23 int dist(Pt A,Pt B) { 24 return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y); 25 } 26 27 int n; 28 vector<Pt> ConvexHull(vector<Pt> p) { 29 sort(p.begin(),p.end()); 30 p.erase(unique(p.begin(),p.end()),p.end()); 31 int n=p.size(); 32 int m=0; 33 vector<Pt> ch(n+1); 34 for(int i=0;i<n;i++) { 35 while(m>1 && cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--; 36 ch[m++]=p[i]; 37 } 38 int k=m; 39 for(int i=n-2;i>=0;i--) { 40 while(m>k && cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--; 41 ch[m++]=p[i]; 42 } 43 if(n>1) m--; 44 ch.resize(m); 45 return ch; 46 } 47 48 int diameter(vector<Pt> ps) { //旋转卡壳 49 vector<Pt> p=ConvexHull(ps); 50 int n=p.size(); 51 if(n==1) return 0; //特殊情况处理 52 if(n==2) return dist(p[0],p[1]); 53 p.push_back(p[0]); //for u 54 int ans=0; 55 for(int u=0,v=1;u<n;u++) { 56 for(;;) { 57 int diff=cross(p[u+1]-p[u],p[v+1]-p[v]); 58 if(diff<=0) { //此时uv为对踵点 59 ans=max(ans,dist(p[u],p[v])); 60 if(!diff) ans=max(ans,dist(p[u],p[v+1])); //平行 61 break; 62 } 63 v=(v+1)%n; 64 } 65 } 66 return ans; 67 } 68 void read(int& x) { 69 char c=getchar(); 70 while(!isdigit(c)) c=getchar(); 71 x=0; 72 while(isdigit(c)) 73 x=x*10+c-'0' , c=getchar(); 74 } 75 int main() { 76 int T; 77 read(T); 78 while(T--) { 79 int n; read(n); 80 vector<Pt> ps; 81 for(int i=0;i<n;i++) { 82 int x,y,w; 83 read(x),read(y),read(w); 84 ps.push_back(Pt(x,y)); 85 ps.push_back(Pt(x+w,y)); 86 ps.push_back(Pt(x,y+w)); 87 ps.push_back(Pt(x+w,y+w)); 88 } 89 printf("%d ",diameter(ps)); 90 } 91 return 0; 92 }