您的位置:首页 > 其它

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

2016-02-01 19:43 399 查看
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17267

【思路】

凸包+旋转卡壳

求出凸包,用旋转卡壳算出凸包的直径即可。

【代码】

#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;

struct Pt {
int x,y;
Pt(int x=0,int y=0):x(x),y(y) {};
};
typedef Pt vec;

vec operator - (Pt A,Pt B) { return vec(A.x-B.x,A.y-B.y); }
bool operator < (const Pt& a,const Pt& b) {
return a.x<b.x || (a.x==b.x && a.y<b.y);
}
bool operator == (const Pt& a,const Pt& b) {
return a.x==b.x && a.y==b.y;
}

int Dot(vec A,vec B) { return A.x*B.x+A.y+B.y; }
int cross(vec A,vec B) { return A.x*B.y-A.y*B.x; }
int dist(Pt A,Pt B) {
return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
}

int n;
vector<Pt> ConvexHull(vector<Pt> p) {
sort(p.begin(),p.end());
p.erase(unique(p.begin(),p.end()),p.end());
int n=p.size();
int m=0;
vector<Pt> ch(n+1);
for(int i=0;i<n;i++) {
while(m>1 && cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
ch[m++]=p[i];
}
int k=m;
for(int i=n-2;i>=0;i--) {
while(m>k && cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
ch[m++]=p[i];
}
if(n>1) m--;
ch.resize(m);
return ch;
}

int diameter(vector<Pt> ps) {                                //旋转卡壳
vector<Pt> p=ConvexHull(ps);
int n=p.size();
if(n==1) return 0;                                        //特殊情况处理
if(n==2) return dist(p[0],p[1]);
p.push_back(p[0]);                                        //for u
int ans=0;
for(int u=0,v=1;u<n;u++) {
for(;;) {
int diff=cross(p[u+1]-p[u],p[v+1]-p[v]);
if(diff<=0) {                                    //此时uv为对踵点
ans=max(ans,dist(p[u],p[v]));
if(!diff) ans=max(ans,dist(p[u],p[v+1]));     //平行
break;
}
v=(v+1)%n;
}
}
return ans;
}
void read(int& x) {
char c=getchar();
while(!isdigit(c)) c=getchar();
x=0;
while(isdigit(c))
x=x*10+c-'0' , c=getchar();
}
int main() {
int T;
read(T);
while(T--) {
int n; read(n);
vector<Pt> ps;
for(int i=0;i<n;i++) {
int x,y,w;
read(x),read(y),read(w);
ps.push_back(Pt(x,y));
ps.push_back(Pt(x+w,y));
ps.push_back(Pt(x,y+w));
ps.push_back(Pt(x+w,y+w));
}
printf("%d\n",diameter(ps));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: