HDU 3532 Max Angle(计算几何——极角排序)

来源:互联网 发布:淘宝xboxone手柄 编辑:程序博客网 时间:2024/05/22 05:04

Description

Given manypoints in a plane, two players are playing an interesting game. 

Player1 selects one point A as the vertex(
顶点) of an angle. Then player2 selects other two points Band C. A, B and C are different with each other. Now they get an angle B-A-C. 

Player1 wants to make the angle as large as possible, while player2 wants tomake the angle as small as possible. 

Now you are supposed to find the max angle player1 can get, assuming play2 is clever enough. 

Input

There are manytest cases. In each test case, the first line is an integer n (3 <= n <=1001), which is the number of points on the plane. Then there are n lines. Eachcontains two floating number x, y, witch is the coordinate of one point. n<= 0 denotes the end of input.

Output

For each testcase, output just one line, containing the max angle player1 can get in degreeformat. The result should be accurated up to 4 demicals.

Sample Input

3

0 0

2 0

0 5

-1

Sample Output

90.0000

题意:给一个平面上标许多点,两个表演者正在玩一个有趣的游戏,玩家1选择一个角A作为顶点,玩家2选择B、C两点,A、B、C各不相同,现在他们到达B-A-C,玩家1想使角尽可能的大,玩家2恰恰相反,现在你的任务是找到玩家1的最大角,假设玩家2是非常聪明的

输入:多组测试数据,在每组测试数据中,第一行是一个数字n代表飞机上的点的个数,接下来n行中的每行有两个浮点数,代表点的坐标,n<=0结束

输出:对于每个测试数据,输出一行,包含一个玩家1能够到达的最大角

解题思路:

         由于题意是使玩家1选择的点到其他两点所组成的夹角最大,而玩家2是选择两点使玩家1到该两点夹角最小。

         先定一个A点作为玩家1的点,然后再从余下的n-1个点中选出B、C点两点,即最坏的两个点,那么可以先枚举A点作为外层循环然后再从剩下的点中选出两个最坏的点,选的方法是选用斜率(与X轴的斜率)最相近的两个点,利用排序即可,然后再逐渐选出最大角。

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <vector>#include <queue>#include <algorithm>#include <set>using namespace std;typedef long long LL;typedef unsigned long long ULL;const int INF = 1e9+5;const int MAXN = 1e6+5;const int MOD = 1e9+7;const double eps = 1e-7;const double PI = acos(-1);struct Point{    double x, y;}p[MAXN];double num[MAXN];int main(){    int n;    while(~scanf("%d",&n))    {        if(n <= 0)            break;        for(int i=0; i<n; i++)            scanf("%lf%lf",&p[i].x,&p[i].y);        double ans = 0;        for(int i=0; i<n; i++)        {            int sum = 0;            double Min = 5211314;            for(int j=0; j<n; j++)            {                if(i == j)                    continue;                double xx = p[j].x - p[i].x;                double yy = p[j].y - p[i].y;                num[sum] = atan2(yy,xx)/PI*180;///点(yy,xx) 与 X 轴的夹角                if(num[sum] < 0)                    num[sum] += 360;///保证是正数                sum++;            }            sort(num, num+sum);            double tmp = 0;            for(int j=1; j<sum; j++)            {                tmp = num[j]-num[j-1];///相邻角                Min = min(tmp, Min);///最小值              //  cout<<"Min1:"<<Min<<endl;               // cout<<"tmp1:"<<tmp<<endl;            }      ans = max(ans, Min);        }        printf("%.4lf\n",ans);    }    return 0;}


0 0
原创粉丝点击