POJ 1696 求最小极角

题目大意: 很简单的意思,蚂蚁只能向左转,求最多走的点数和路径

想法: 每个点都能遍历到,先弄清楚这点,然后发现规律是对于每次到达的一个点,下个点都是对与当前点极角最小的。O(n^2)时间过,0ms.....

角度排序用cross叉积就可以了


代码:


#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#define cross(p1,p2,p3) ((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))
#define crossOp(p1,p2,p3) sign(cross(p1,p2,p3))
using namespace std;

const double EPS = 1e-8;
inline int sign(double a) {
	return a < -EPS ? -1 : a > EPS;
}
struct Point {
	double x, y;
	int id;
	Point() {
	}
	Point(double _x, double _y) :
			x(_x), y(_y) {
	}
	Point operator+(const Point&p) const {
		return Point(x + p.x, y + p.y);
	}
	Point operator-(const Point&p) const {
		return Point(x - p.x, y - p.y);
	}
	Point operator*(double d) const {
		return Point(x * d, y * d);
	}
	Point operator/(double d) const {
		return Point(x / d, y / d);
	}
	bool operator<(const Point&p) const {
		int c = sign(x - p.x);
		if (c)
			return c == -1;
		return sign(y - p.y) == -1;
	}
	double dot(const Point&p) const {
		return x * p.x + y * p.y;
	}
	double det(const Point&p) const {
		return x * p.y - y * p.x;
	}
	double alpha() const {
		return atan2(y, x);
	}
	double distTo(const Point&p) const {
		double dx = x - p.x, dy = y - p.y;
		return hypot(dx, dy);
	}
	double alphaTo(const Point&p) const {
		double dx = x - p.x, dy = y - p.y;
		return atan2(dy, dx);
	}
	void read() {
		scanf("%d%lf%lf", &id,&x, &y);
	}
	double abs() {
		return hypot(x, y);
	}
	double abs2() {
		return x * x + y * y;
	}
	void write() {
		cout << "(" << x << "," << y << ")" << endl;
	}
};
Point temp;
bool cmp(Point a,Point b)
{
    return a.y<b.y;
}
bool cmp_angel(Point a,Point b)
{
    int t=crossOp(temp,a,b);
    if(t<0) return false; //说明a的再b的顺时针方向上,说明极角小
    else if(t>0) return true;
    else
    {
        int da=temp.distTo(a);
        int db=temp.distTo(b);
        if(da<=db)return false ;
        else return true;
    }
}
Point p[51];
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        p[i].read();
        sort(p+1,p+1+n,cmp);
        temp=p[1];
        cout<<n<<" ";
        cout<<p[1].id<<" ";
        for(int i=2;i<=n;i++)
        {
            sort(p+i,p+1+n,cmp_angel);
            temp=p[i];
            cout<<p[i].id<<" ";
        }
        cout<<endl;
    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值