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

传送门

Max Angle

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 704    Accepted Submission(s): 253


Problem Description
Given many points 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 B and 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 to make the angle as small as possible.

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

Input
There are many test 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. Each contains two floating number x, y, witch is the coordinate of one point. n <= 0 denotes the end of input.
 

Output
For each test case, output just one line, containing the max angle player1 can get in degree format. The result should be accurated up to 4 demicals.
 

Sample Input
  
  
3
0 0
2 0
0 5
-1
 

Sample Output
  
  
90.0000


题目大意:
平面上有 n 个点,现在有两个玩家,玩家1选一个点 A ,玩家2选两个点 B C ,这三个点两两不相同,然后这三个点组成一个夹角 B-A-C,玩家1想想让这个角尽可能大,玩家2想让这个角尽可能小,然后以玩家1的角度来看,输出最大的角度。
解题思路:
这个题目就是枚举,首先我们让玩家1 先选取一个点,然后开始枚举剩下的两个点可是这样是超时的,那么我们要考虑怎么求这个夹角呢,那肯定是玩家1选的那个点与其他点的斜率,然后我们就可以跑两重循环,第一重循环是枚举玩家1需要的点,然后第二重循环枚举玩家2 需要的点,首先我们计算斜率,然后计算与 X 轴的夹角,然后排序,相邻的夹角取最小的就达到了玩家2的目的,然后在最小的里面找最大值,输出最大值就行了。
My Code

/**
2016 - 08 - 04 上午
Author: ITAK

Motto:

今日的我要超越昨日的我,明日的我要胜过今日的我,
以创作出更好的代码为目标,不断地超越自己。
**/

#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 Cross(Point a, Point b, Point c)
{
    return (b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x);
}
double dis(Point a, Point b)
{
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
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);///最小值
            }
            tmp = 360 - num[sum-1] + num[0];
            Min = min(tmp, Min);
            ans = max(ans, Min);
        }
        printf("%.4lf\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值