【题目大意】
发射器的发射范围是一个半圆,圆心半径给出,角度任意。在平面上给出N个点,问发射器最多可以覆盖多少个。
【解题思路】
算夹角,排序,统计。
【源代码】
#include <cstdio>
#include <cstring>
#include <math.h>
#include <algorithm>
using namespace std;
#define maxn 2010
double const EPS=1e-8;
double const PI=acos(-1.0);
int max(int x, int y){return (x>y)?x:y;}
int main(){
double a[maxn], r, rr;
int cs, n, x, y, xx, yy, same, cnt, k;
while (scanf("%d%d%lf", &x, &y, &r)==3 && r>0)
{
scanf("%d", &n);
k=0;
for (int i=0; i<n; i++)
{
scanf("%d%d", &xx, &yy);
xx-=x;
yy-=y;
rr=hypot(1.0*xx, 1.0*yy);
if (rr<r+EPS) //rr<=r
a[k++]=atan2(yy,xx);
}
sort(a,a+k);
for (int j=0; j<k; j++)
{
a[k+j]=a[j]+2*PI;
}
cnt=0;
for (int i=0, j=0; i<k; i++)
{
//a[j]<=a[i]+PI
while (a[j]<a[i]+PI+EPS)
j++;
cnt=max(cnt,j-i);
}
printf("%d\n", cnt);
}
return 0;
}
【相关参考】
1、math库
转自:http://virus.blog.51cto.com/51437/23338
(1)三角函数
double sin (double);
double cos (double);
double tan (double);
(2)反三角函数
double asin (double); 结果介于[-PI/2, PI/2]
double acos (double); 结果介于[0, PI]
double atan (double); 反正切(主值), 结果介于[-PI/2, PI/2]
double atan2 (double, double); 反正切(整圆值), 结果介于[-PI, PI] (原文有误)
(3)双曲三角函数
double sinh (double);
double cosh (double);
double tanh (double);
(4)指数与对数
double exp (double);
double pow (double, double);
double sqrt (double);
double log (double); 以e为底的对数
double log10 (double);
(5) 取整
double ceil (double); 取上整
double floor (double); 取下整
(6) 绝对值
double fabs (double);
(7)标准化浮点数
double frexp (double f, int *p); 标准化浮点数, f = x * 2^p, 已知f求x, p ( x介于[0.5, 1] )
double ldexp (double x, int p); 与frexp相反, 已知x, p求f
(8)取整与取余
double modf (double, double*); 将参数的整数部分通过指针回传, 返回小数部分
double fmod (double, double); 返回两参数相除的余数
2、atan2的具体讨论
原文《C语言math.h库函数中atan与atan2的区别》
转自:http://blog.csdn.net/tuyang120428941/archive/2010/08/18/5822041.aspx
1.atan()接受一个参数:
angel=atan(slope)
angel为一个角度的弧度值,要换算成角度,必须乘以180/PI,slope为直线的斜率,是一个数字,这个数字可以是负的无穷大到正无穷大之间的任何一个值.
不过,利用他进行计算比较复杂.由于三角函数的周期性,一个数字的反正切值不止一个.例如arctan(1)的值是pi/4 + k * pi.然而通过atan(1)只能得到PI/4,对于正切函数来说,他的周期是180度,所以两个相差180度的角具有相同的正切和斜率:
tanθ=tan(θ+180)
然而,atan()只能返回一个角度值,因此确定他的角度非常的复杂。特别是用在处理图像旋转的问题的时候更是棘手,因为我们要通过这个角度来判断图像是顺时针旋转还是逆时针旋转,从而来确定图像的转动,然而这个函数很难做到。
2.atan2()接受两个参数x和y:
angel=Math.atan2(y,x)
x 指定两个点横坐标的差
y 指定两个点纵坐标的差
计算出来的结果angel是一个弧度值,要换算成角度,也必须乘以180/PI。
double a = atan2(1,1);
double b = atan2(1,-1);
double c = atan2(-1,-1);
double d = atan2(-1,1);
double e = atan(1);
double f = atan(-1);
cout << a * 180/PI << endl; 45 //第一象限
cout << b * 180/PI << endl; 135 //第二象限
cout << c * 180/PI << endl; -135 //第三象限
cout << d * 180/PI << endl; -45 //第四象限
cout << e * 180/PI << endl; 45
cout << f * 180/PI << endl; -45
以下是用于图像旋转的代码:与这两个函数的讨论无关......
由于计算机中坐标向右是正X轴方向,向下是正Y轴方向,所以计算机坐标中的4,3,2,1象限就对应数学课本中的1,2,3,4象限。于是得知atan2的取值是-PI到PI。
3、 hypot
功 能: 计算直角三角形的斜边长
用 法: double hypot(double x, double y);