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

题目链接: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=,int y=):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=;
vector<Pt> ch(n+);
for(int i=;i<n;i++) {
while(m> && cross(ch[m-]-ch[m-],p[i]-ch[m-])<=) m--;
ch[m++]=p[i];
}
int k=m;
for(int i=n-;i>=;i--) {
while(m>k && cross(ch[m-]-ch[m-],p[i]-ch[m-])<=) m--;
ch[m++]=p[i];
}
if(n>) m--;
ch.resize(m);
return ch;
} int diameter(vector<Pt> ps) { //旋转卡壳
vector<Pt> p=ConvexHull(ps);
int n=p.size();
if(n==) return ; //特殊情况处理
if(n==) return dist(p[],p[]);
p.push_back(p[]); //for u
int ans=;
for(int u=,v=;u<n;u++) {
for(;;) {
int diff=cross(p[u+]-p[u],p[v+]-p[v]);
if(diff<=) { //此时uv为对踵点
ans=max(ans,dist(p[u],p[v]));
if(!diff) ans=max(ans,dist(p[u],p[v+])); //平行
break;
}
v=(v+)%n;
}
}
return ans;
}
void read(int& x) {
char c=getchar();
while(!isdigit(c)) c=getchar();
x=;
while(isdigit(c))
x=x*+c-'' , c=getchar();
}
int main() {
int T;
read(T);
while(T--) {
int n; read(n);
vector<Pt> ps;
for(int i=;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 ;
}
上一篇:SourceTree 免登录跳过初始设置 - 转


下一篇:H5WebSocket前后台代码