POJ 2007(卷包裹算法(Gift Wrapping Algorithm)+ostream)

Language:
Scrambled Polygon
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 5602   Accepted: 2664

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;
}