原题链接

题目大意:有一个发射站,覆盖范围是半径一定的一个半圆。在一个1000*1000平方米的地盘里有很多接收站。给定发射站的圆心,求最佳角度时能覆盖接收站的个数。

解法:本质上就是给一个原点和其他若干点,找出一个可以覆盖最多点的半圆。用了两个函数判断,一个是判断两点之间的距离,即该点到原点的距离是否在半径之内,筛选出第一步满足的点。另一个是判断两个点A、B是否在同一个半圆内,其实先确定一条直线AO,然后规定B点在AO的左侧就算在半圆内。每个点都遍历一次,找出最大值即可。

 

参考代码:

#include<iostream>
#include<cmath>

using namespace std;
bool isInclude(int xx, int yy);
bool isCovered(int*, int*);
double cx,cy,r;


int main(){
	
	int xx,yy,point[150][2];
	int i,j,k,n,m,count,max;

	while(cin>>cx>>cy>>r&&r>=0){
		cin>>n;
		m=0;
		max=0;
		for(i=0;i<n;i++){
			cin>>xx>>yy;
			if(isInclude(xx,yy)){
				point[m][0]=xx;
				point[m][1]=yy;
				m++;
			}
		}
		for(j=0;j<m;j++){
			count=1;
			for(k=0;k<m;k++){
				if(k==j)continue;
				if(isCovered(point[j],point[k]))
					count++;
				if(count>max)
					max=count;
			}
		}
		cout<<max<<endl;	
	}

	return 0;
}

bool isInclude(int xx,int yy){
	double d;
	d=(xx-cx)*(xx-cx)+(yy-cy)*(yy-cy);  //求两点的欧式距离
	d=sqrt(d);
	if(d<=r)
		return true;
	else
		return false;
}

bool isCovered(int *A, int *B){
	int ax,ay,bx,by;
	double cc;
	ax=A[0];bx=B[0];
	ay=A[1];by=B[1];
	cc=(ax-cx)*(by-cy)-(ay-cy)*(bx-cx);//判断点是否在直线的同一侧
	if(cc>0)
		return false;
	else
		return true;
}