此题链接单击这里
================
题意:
在X轴上半轴有n个小岛,给出每个小岛座标。以X轴为圆心画半径为d的圆,问最少画多少个圆才能把所有的小岛覆盖起来。
思路:
这是一个区间选点问题,先以每个小岛为圆心,d为半径,找到圆与X轴相交的左右端点或相切的点(把圆的方程变换一下,变成求x的方程)。求得的所有的区间进行重合判断。(输入的小岛的纵座标一定大于等于d,否定就直接输出-1)
给出变换公式
(x−a)2+(y−b)2=d2
⇒(x−a)2=d2−(y−b)2
⇒(x−a)=d2−(y−b)2−−−−−−−−−−√
⇒x=a±d2−(y−b)2−−−−−−−−−−√
因为点在x轴上
⇒x=a±d2−b2−−−−−−√
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
struct str
{
double x,y;
} a[1010];
bool cmp(str a1,str a2)
{
if(a1.y!=a2.y)
return a1.y<a2.y;
return a1.x>a2.x;
}
int main()
{
int n,d;
int Case=1;
while(cin>>n>>d&&(n+d))
{
int loge=0;
for(int i=0; i<n; i++)
{
int x,y;
cin>>x>>y;
if(y>d)
loge=1;
a[i].x=x-sqrt(d*d-y*y);
a[i].y=x+sqrt(d*d-y*y);
}
if(loge)
{
printf("Case %d: %d\n",Case++,-1);
continue;
}
sort(a,a+n,cmp);
double q=a[0].y;
int sum=1;
for(int i=1; i<n; i++)
{
if(a[i].x<=q)
continue;
q=a[i].y;
sum++;
}
printf("Case %d: %d\n",Case++,sum);
}
return 0;
}
有问题联系企鹅791267032
邮箱地址….wutanrong@Hotmail.com