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; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值