uva11626凸包路径

来源:互联网 发布:淘宝客链接转发微信 编辑:程序博客网 时间:2024/06/03 14:43

题目链接


https://vjudge.net/problem/UVA-11626
 就是凸包但是不要舍弃在一条直线上的点即可

#include <bits/stdc++.h>using namespace std;struct point{    double x,y,d;};point P[ 100001];point S[ 100001];point MP;int countn = 0;int N;double crossproduct( point a, point b, point c )//ab到ac{    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}double dist( point a, point b ){    return sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y));}int cmp1( point a, point b){    if ( a.x == b.x ) return a.y < b.y;    else return a.x < b.x;}bool cmp2( point a, point b){    return crossproduct( P[0], a, b ) > 0;}bool cmp3( point a, point b){    double cp = crossproduct( P[0], a, b );    if ( cp == 0.0 ) {        if ( !crossproduct( P[0], a, MP ) )//在回边上            return a.d > b.d;        else return a.d < b.d;    }else return cp > 0;}struct asshole{    void input()    {        countn = 0;        scanf("%d",&N);        char C;        for ( int i = 0 ; i < N ; ++ i ) {            scanf("%lf %lf %c",&P[countn].x,&P[countn].y,&C);            if ( C == 'Y' ) countn++;        }    }    void Graham(int cnt)    {        sort(P, P + cnt, cmp1);        sort( P+1, P+cnt, cmp2);        //处理共线        for ( int i = 1 ; i < cnt ; ++ i )            P[i].d = dist( P[0], P[i] );        MP = P[cnt-1];        sort( P+1, P+cnt, cmp3 );        int top = -1;        if ( cnt> 0 ) S[++ top] = P[0];        if ( cnt> 1 ) S[++ top] = P[1];        if ( cnt> 2 ) {            S[++ top] = P[2];            for ( int i = 3 ; i < cnt ; ++ i ) {                while ( crossproduct( S[top-1], S[top], P[i] ) < 0 ) -- top;                S[++ top] = P[i];            }        }        printf("%d\n",top+1);        for ( int i = 0 ; i <= top ; ++ i )            printf("%.0f %.0f\n",S[i].x,S[i].y);    }}ja;int main(){    int T;    while ( scanf("%d",&T) != EOF )    while ( T -- ) {        ja.input();        ja.Graham(countn);    }    return 0;}
原创粉丝点击