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;
}