凸包总结

这几天终于开始学了计算几何了,整个人都萌萌哒~~~

首先当然是凸包啦~~~

凸包的算法还不算难啦,就是找到一定在凸包上的点,然后就按这个点为o点按极角排序,然后就弄个栈维护啦~~~

然后就做几道题啦~~~

poj 1113 WALL

这道题直接求出凸包的长度加个圆就行了

第一次打凸包弄到死,结果是while写成if了= =

CODE:

#include<cstdio>

#include<iostream>

#include<cstring>

#include<algorithm>

#include<cmath>

using namespace std;

#define fi first

#define se second

#define sqr(x) ((x)*(x))

typedef pair<int,int> ii;

#define pi acos(-1.0)

ii dec(ii x,ii y){

return ii(x.fi-y.fi,x.se-y.se);

}

int cross(ii x,ii y){

return (x.fi*y.se-x.se*y.fi);

}

int dist(ii x){

return sqr(x.fi)+sqr(x.se);

}

#define maxn 1010

ii a[maxn];

bool cmp(ii x,ii y){

int m=cross(dec(a[1],x),dec(a[1],y));

if (m!=0) return m>0;

return (dist(dec(a[1],x))<dist(dec(a[1],y)));

}

int n,l,q[maxn],r;

double ans;

int main(){

scanf("%d%d",&n,&r);

int x=1;

for (int i=1;i<=n;i++) {

scanf("%d%d",&a[i].fi,&a[i].se);

if (a[x].second>a[i].second||(a[x].second>a[i].second&&a[x].fi>a[i].fi)) x=i;

}

swap(a[1],a[x]);

sort(a+2,a+1+n,cmp);

q[1]=1;q[2]=2;l=2;

for (int i=3;i<=n;i++) {

while (l>1&&cross(dec(a[q[l-1]],a[q[l]]),dec(a[q[l]],a[i]))<=0) l--;

q[++l]=i;

}

q[l+1]=1;

for (int i=1;i<=l;i++) {

ans+=sqrt(dist(dec(a[q[i]],a[q[i+1]]) ) );

}

ans+=2.0*pi*(double)r;

printf("%.0f",ans);

return 0;

}

poj 1228 Grandpa's Estate

奇怪的题意,直接把凸包求出来然后判断每条边是否有3个点就行了

1A了真开心

CODE:

#include<cstdio>

#include<iostream>

#include<cstring>

#include<algorithm>

using namespace std;

typedef pair<int,int> ii;

#define fi first

#define se second

ii dec(ii x,ii y){

return ii(x.fi-y.fi,x.se-y.se);

}

int cross(ii x,ii y){

return x.fi*y.se-x.se*y.fi;

}

#define sqr(x) ((x)*(x))

int dist(ii x){

return sqr(x.fi)+sqr(x.se);

}

ii a[1010];

bool cmp(ii x,ii y){

int m=cross(dec(a[1],x),dec(a[1],y));

if (m==0) return dist(dec(a[1],x))<dist(dec(a[1],y));

return m>0;

}

bool jiao(ii x,ii y,ii z){

int x1=min(x.fi,y.fi),x2=max(x.fi,y.fi);

int y1=min(x.se,y.se),y2=max(x.se,y.se);

if (z.fi<x1||z.fi>x2||z.se<y1||z.se>y2) return 0;

return cross(dec(x,z),dec(x,y))==0;

}

int n;

int init(){

scanf("%d",&n);

int root=1;

for (int i=1;i<=n;i++) {

scanf("%d %d",&a[i].fi,&a[i].se);

root=a[i]<a[root]?i:root;

}

swap(a[1],a[root]);

}

int q[1010];

int work(){

sort(a+2,a+1+n,cmp) ;

q[1]=1;q[2]=2;int l=2;

for (int i=3;i<=n;i++){

while (l>1&&cross(dec(a[q[l-1]],a[q[l]]),dec(a[q[l]],a[i]))<=0) l--;

q[++l]=i;

}

q[l+1]=1;bool flag=1;

for (int i=1;i<=l;i++) {

int cnt=0;

for (int j=1;j<=n;j++)

if (jiao(a[q[i]],a[q[i+1]],a[j])) cnt++;

if (cnt<3||cnt==n) flag=0;

}

printf("%s ",flag?"YES":"NO");

return 0;

}

int main(){

int T;

scanf("%d",&T);

while (T--) {

init();

work();

}

return 0;

}

还有一道杂题

poj 2007 Scrambled Polygon

直接按极角排然后输出就行了

CODE:

#include<cstdio>

#include<iostream>

#include<algorithm>

#include<cstring>

using namespace std;

#define fi first

#define se second

#define maxn 100

typedef pair<int,int> ii;

ii a[maxn];

int n;

ii dec(ii x,ii y){

return ii(x.fi-y.fi,x.se-y.se);

}

int cross(ii x,ii y){

return x.fi*y.se-x.se*y.fi;

}

bool cmp(ii x,ii y){

return cross(dec(a[1],x),dec(a[1],y))>0;

}

int main(){

n=1;

while (scanf("%d%d",&a[n].fi,&a[n].se)!=EOF) n++;

n--;

sort(a+2,a+1+n,cmp);

for (int i=1;i<=n;i++) printf("(%d,%d) ",a[i].fi,a[i].se);

return 0;

}

好了接下来就是半平面交了,加油!!


原文地址:https://www.cnblogs.com/New-Godess/p/4348915.html