Language:
Scrambled Polygon
Description
凸包求法如图:
![]() ![]() Input
点数不超过 50.每行输入的坐标为整数且范围在 -999..999. 数据以(0,0)开头,保证所有点必能构成凸包,除第1个点外没有点在坐标轴上或第二象限,没用三点共线.
Output
每行输出一个坐标(x,y),以(0,0)开头,逆时针输出.
Sample Input 0 0 70 -50 60 30 -30 -50 80 20 50 -60 90 -20 -30 -40 -10 -60 90 10 Sample Output (0,0) (-30,-40) (-30,-50) (-10,-60) (50,-60) (70,-50) (90,-20) (90,10) (80,20) (60,30) Source |
注意istream和ostream的写法
它必须是友元函数(如果是成员函数,则必须以const P为开头,这显然不行)
它返回一个指向ostream的指针,前面可以接ostream(cout<<a<<b;),还有一个元素(要输入的)
friend ostream& operator<<(ostream& cout,P &a)
{
cout<<"("<<a.x<<','<<a.y<<')'<<endl; //把要输出的内容推进输出流
return cout;
}
接下来讲卷包裹算法:
我们先找到一个在凸包上的点,然后卷过去
伪代码如下:
初始化st[]=0,j=0,endpoint=P0
do
{
将endpoint加入队列st.
找到任意从P0点出发,转向最右的点P
endpoint=P
}until endpoint=P0
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<functional>
using namespace std;
#define MAXN (50+10)
struct P
{
int x,y;
P(){}
P(int _x,int _y):x(_x),y(_y){}
friend ostream& operator<<(ostream& cout,P &a)
{
cout<<"("<<a.x<<','<<a.y<<')'<<endl;
return cout;
}
}a[MAXN];
struct V
{
int x,y;
V(){}
V(int _x,int _y):x(_x),y(_y){}
V(P A,P B):x(B.x-A.x),y(B.y-A.y){}
};
int operator*(V a,V b)
{
return a.x*b.y-a.y*b.x;
}
int n,st[MAXN];
int main()
{
// freopen("poj2007.in","r",stdin);
int n=1;
while (scanf("%d%d",&a[n].x,&a[n].y)!=-1) n++; //scanf读入失败返回-1
n--;
int endpoint=1,j=1;
do
{
cout<<a[st[j++]=endpoint];
int k=(endpoint+1)%n+1;
for (int i=1;i<=n;i++)
if (endpoint!=i&&V(a[endpoint],a[i])*V(a[endpoint],a[k])>0) k=i;
endpoint=k;
// cout<<endpoint<<' ';
}while (endpoint!=1);
return 0;
}