1. 程式人生 > >poj 2187 Beauty Contest——旋轉卡殼

poj 2187 Beauty Contest——旋轉卡殼

sort 叉積 detail targe tps i++ target clas pri

題目:http://poj.org/problem?id=2187

學習材料:https://blog.csdn.net/wang_heng199/article/details/74477738

     https://www.jianshu.com/p/74c25c0772d6

可以再倒著枚舉一遍那樣求凸包。

用叉積算面積來旋轉卡殼。

註意在面積等於的時候就不要往後走了,不然只有兩個點的數據就會死循環。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define db double
using
namespace std; const int N=5e4+5; int n,sta[N],top,ans; struct Node{ int x,y; Node(int a=0,int b=0):x(a),y(b) {} bool operator< (const Node &b)const {return x<b.x||(x==b.x&&y<b.y);} Node operator- (const Node &b)const {return Node(x-b.x,y-b.y);} }t[N],a[N]; int rdn() {
int ret=0;bool fx=1;char ch=getchar(); while(ch>9||ch<0){if(ch==-)fx=0;ch=getchar();} while(ch>=0&&ch<=9)ret=ret*10+ch-0,ch=getchar(); return fx?ret:-ret; } int Mx(int a,int b){return a>b?a:b;} int cross(Node u,Node v){return u.x*v.y-u.y*v.x;} int Sqr(int x){return
x*x;} int dist(Node u,Node v){return Sqr(u.x-v.x)+Sqr(u.y-v.y);} void rtc() { a[n+1]=a[1]; for(int i=1,p=2;i<=n;i++) { while(cross(a[p+1]-a[i],a[p+1]-a[i+1])>cross(a[p]-a[i],a[p]-a[i+1]))//> {p++;if(p>n)p=1;}//for if only 2 ver!!! ans=Mx(ans,Mx(dist(a[p],a[i]),dist(a[p+1],a[i+1]))); // ans=Mx(ans,Mx(dist(a[p],a[i+1]),dist(a[p-1],a[i]))); } } int main() { int tot=rdn(); for(int i=1;i<=tot;i++)t[i].x=rdn(),t[i].y=rdn(); sort(t+1,t+tot+1); for(int i=1;i<=tot;i++) { while(top>1&&cross(t[i]-t[sta[top]],t[i]-t[sta[top-1]])>=0)top--; sta[++top]=i; } for(int i=tot-1,lm=top;i;i--) { while(top>lm&&cross(t[i]-t[sta[top]],t[i]-t[sta[top-1]])>=0)top--;///top>lm sta[++top]=i; } n=top-1; for(int i=1;i<=n;i++)a[i]=t[sta[i]]; rtc(); printf("%d\n",ans); return 0; }

poj 2187 Beauty Contest——旋轉卡殼