这一题,,其实不是凸包,因为他给的点已经在凸包上了所以根本不用建凸包啦,,,,只需要对点进行极角排序就能过
注意这个要逆时针输出所以对于起点会有两条边一条为出边一条为回边,两条边排序结果不同所以我排两次
然后!!!!!!!!!!!!!!还有一个很坑的地方用cout<<p[i].x<<" "<<p[i].y<<endl;这样输出是不对的
因为你把整数读入存为小数的时候比如3会变成3.000000000001,所以输出的时候要用printf!!!!今天学到了!!!!
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn=111111;
const double eps=1e-8;
const double PI=acos(-1.0);
int sgn(double x)
{
if(fabs(x)<eps)
return 0;
if(x<0)
return -1;
else
return 1;
}
struct Point
{
double x,y;
Point(){}
Point(double _x,double _y)
{
x=_x;
y=_y;
}
Point operator -(const Point &b)const
{
return Point(x-b.x,y-b.y);
}
double operator ^(const Point &b)const
{
return x*b.y-y*b.x;
}
double operator *(const Point &b)const
{
return x*b.x+y*b.y;
}
};
int m;
Point p[maxn];
double dist(Point a,Point b)
{
return sqrt((a-b)*(a-b));
}
bool cmp1(Point a,Point b)
{
int ans=sgn((a-p[0])^(b-p[0]));
if(ans==1)
return true;
else if(ans==0)
return dist(a,p[0])<dist(b,p[0]);
else
return false;
}
bool cmp2(Point a,Point b)
{
int ans=sgn((a-p[0])^(b-p[0]));
if(ans==1)
return true;
else if(ans==0)
{
int t=sgn((p[1]-p[0])^(a-p[0]));
if(t==0)
return dist(a,p[0])<dist(b,p[0]);
else
return dist(a,p[0])>dist(b,p[0]);
}
else
return false;
}
int Stack[maxn];
int top;
int cont;
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
while(n--)
{
cin>>m;
cont=0;
for(int i=0;i<m;i++)
{
char c;
double x,y;
scanf("%lf %lf %c",&x,&y,&c);
if(c=='Y')
{
p[cont++]=Point(x,y);
}
}
for(int i=0;i<cont;i++)
{
if(p[i].x<p[0].x||(p[0].x==p[i].x&&p[i].y<p[0].y))
swap(p[i],p[0]);
}
sort(p+1,p+cont,cmp1);
sort(p+1,p+cont,cmp2);
//cout<<top<<endl;
/*for(int i=0;i<top;i++)
cout<<p[Stack[i]].x<<" "<<p[Stack[i]].y<<endl;*/
cout<<cont<<endl;
for(int i=0;i<cont;i++)
printf("%.0lf %.0lf\n",p[i].x,p[i].y);
/*for(int i=0;i<cont;i++)
cout<<p[i].x<<" "<<p[i].y<<endl;
*/
}
}
return 0;
}