POJ 2007&&Scrambled Polygon &&幾何計算(叉積排序)

題目如下:
Scrambled Polygon
簡單來說題意就是:
亂序給出凸多邊形的頂點座標,要求按逆時 針順序輸出各頂點。給的第一個點一定是 (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

Rocky Mountain 2004
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

這道題主要運用的是叉積排序,我們首先來寫一下叉積排序
首先講到的是矢量的叉積,我們對於矢量的叉積的應用很多,簡單說幾點,比如三角形面積的應用我們可以用到,還有可以判斷是順時針還是逆時針,還可以判斷是否在半球面上。
關於判斷是順時針還是逆時針,我們可以用來判斷點和線段的關係與線段和線段之間的關係
當叉積大於0的時候,在順時針上,小於0時,在逆時針上,等於0的時候,那麼就共線.
叉積排序屬於極角排序的內容,關於極角排序,我們主要有以下幾種方法:
1.利用atan2()函數按極角從小到大排序;
2.利用叉積按極角從小到大排序;
3.先把象限從小到大排序,再利用極角從小到大排序;

但是2方法的精度較高,所以我們一般使用它;
代碼如下:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
const int maxn=75;
using namespace std;
struct vec{
	double x,y;
	vec(int xx,int yy):x(xx),y(yy) {}
	vec(){}
	double operator ^ (const vec & v) const{
		return x*v.y-y*v.x;
	}
};
#define point vec
point f[maxn];
vec operator - (const point &ta,const point &tb)
{
	return vec(ta.x-tb.x,ta.y-tb.y);
}
bool operator < (const point &ta,const point &tb)
{
	if((vec(tb-point(0,0))^vec(ta-point(0,0)))>0)
	return true;
	return false;
}
int main()
{
	int x,y,n=0;
	while(cin>>f[n].x>>f[n].y) 
	++n;
	sort(f+1,f+n);
	cout<<"(0,0)"<<endl;
	for(int i=n-1;i>0;i--)
	{
		cout<<"("<<f[i].x<<","<<f[i].y<<")"<<endl;
	}
	return 0;
}

當然了我們寫模板的話,我們也可以用下面的這種方式來寫:

struct point {
	double x,y;
};
double cha(double a,double b,double ta,double tb)
{
	return (a*tb-ta*b);
}
double judge(point a,point b,point c)
{
	return cha((b.x-a.x),(b.y-a.y),(c.x-a.x),(c.y-a.y));
}
bool jud(point a,point b)
{
	point c;
	c.x=0;
	c.y=0;
	if((judge(c,a,b))==0)
	return a.x<b.x;
	else return judge(c,a,b)>0; 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章