UVA 4728 Squares(凸包+旋转卡壳)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA 4728 Squares(凸包+旋转卡壳)相关的知识,希望对你有一定的参考价值。

 

题目链接: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\n",diameter(ps));
90     }
91     return 0;
92 }

 

以上是关于UVA 4728 Squares(凸包+旋转卡壳)的主要内容,如果未能解决你的问题,请参考以下文章

[luogu1452]Beauty Contest凸包+旋转卡壳

旋转卡壳-求凸包最大直径

BZOJ 1185 [HNOI2007]最小矩形覆盖:凸包 + 旋转卡壳

[hdu3934] 凸包 旋转卡壳

算法复习——凸包加旋转卡壳(poj2187)

旋转卡壳