内容目录
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; }