poj 2007 凸包 极角排序

来源:互联网 发布:土豆客户端 mac 编辑:程序博客网 时间:2024/05/16 17:00

题意:给出凸包上所有的点,一定有点(0,0)。

将点从(0,0)开始逆时针输出


方法1:利用atan2计算角度排序

//double atan2( double y, double x );

//y/x的反正切值,结合所在的象限。 
//是一个弧度值,要换算成角度,也必须乘以180/PI。

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <string>#include <algorithm>using namespace std;const double PI = acos(-1);struct node{    int x,y;//奇怪的是把数据类型由doule改为int就过了};node point[60];bool cmp(const node &a, const node &b){    return atan2(a.y,a.x) < atan2(b.y,b.x);}double cal(double a){    if(a < 0)        return a + 2 * PI;    return a;}int main(){    int cnt = 0,begin;    double tmp = 0,hub;    //freopen("t.txt","r",stdin);    scanf("%d %d", &point[0].x , &point[0].y);    while(scanf("%d %d", &point[cnt].x , &point[cnt].y) != EOF)        cnt++;    sort(point,point+cnt,cmp);//逆时针排序    point[cnt] = point[0];    for(int i = 0; i < cnt; i++)    {        hub = atan2(point[i+1].y,point[i+1].x) - atan2(point[i].y,point[i].x);        if(fabs(hub) > tmp)//找到角度相差就大的两个点,后一个点位起始点        {            tmp = hub;            begin = (i+1)%cnt;        }    }    printf("(0,0)\n");    for(int i = 0; i < cnt; i++)        printf("(%d,%d)\n", point[(i+begin)%cnt].x , point[(i+begin)%cnt].y);    return 0;}


方法2:直接利用叉积排序

题目保证最多出现三个象限的角

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <vector>#include <map>#include <set>#include <queue>#include <stack>#include <string>#include <algorithm>using namespace std;#define pi acos(-1.0)#define maxn struct point{    int x,y;};point node[60];bool cmp(const point &a, const point &b){    int hub;    hub = a.x*b.y - a.y*b.x;    return hub >= 0;}int main(int argc, char const *argv[]){    int cnt = 0;    //freopen("t.txt","r", stdin);    while(scanf("%d %d", &node[cnt].x , &node[cnt].y) != EOF)        cnt++;    //fclose(stdin);    sort(node+1,node+cnt,cmp);    for(int i = 0; i < cnt; i++)        printf("(%d,%d)\n" ,node[i].x, node[i].y);    return 0;}

方法3:按象限分成四份,然后叉积排列


#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <vector>#include <map>#include <set>#include <queue>#include <stack>#include <string>#include <algorithm>using namespace std;typedef __int64 ll;#define inf 0x7fff#define pi acos(-1.0)#define maxn struct point{    int x,y;};point ver[5][60];int num[5];bool cmp(const point &a, const point &b){    int hub;    hub = a.x*b.y - a.y*b.x;//叉积排序,也可以考虑计算斜率    return hub >= 0;}int main(int argc, char const *argv[]){    int cnt = 0,begin;    int a,b;    for(int i = 1; i < 5; i++)        num[i] = 0;    //freopen("t.txt","r", stdin);    scanf("%d %d", &a, &b);    while(scanf("%d %d", &a , &b) != EOF)    {        cnt++;        if(a > 0)        {            if(b > 0)            {                ver[1][num[1]].x = a;                ver[1][num[1]].y = b;                num[1] ++;            }            else            {                ver[4][num[4]].x = a;                ver[4][num[4]].y = b;                num[4] ++;            }        }        else        {            if(b > 0)            {                ver[2][num[2]].x = a;                ver[2][num[2]].y = b;                num[2] ++;            }            else            {                ver[3][num[3]].x = a;                ver[3][num[3]].y = b;                num[3] ++;            }        }    }    //fclose(stdin);        for(int i = 1; i < 5; i++)    {        if(num[i] == 0)            begin = i;        else sort(ver[i],ver[i]+num[i],cmp);    }    printf("(0,0)\n");    for(int i = 1; i < 4; i++)    {        if(i+begin > 4)            begin -= 4;        for(int j = 0; j < num[i+begin]; j++)            printf("(%d,%d)\n" ,ver[i+begin][j].x, ver[i+begin][j].y);    }    return 0;}



0 0
原创粉丝点击