本文系博主原创,转载请注明地址:https://blog.csdn.net/coder_what/article/details/82690880
雷达安装
时间限制: 1000MS | 内存限制: 10000K | |
提交总数: 109120 | 接受: 24128 |
描述
假设滑行是无限直线。土地位于海岸的一侧,海洋位于另一侧。每个小岛都位于海边。并且任何位于滑行的雷达装置只能覆盖d距离,因此如果它们之间的距离最多为d,则可以通过半径装置覆盖海中的岛屿。
我们使用笛卡尔坐标系,定义滑行是x轴。海侧在x轴上方,陆侧在下方。考虑到每个岛屿在海中的位置,并考虑到雷达装置覆盖范围的距离,您的任务是编写一个程序,以找到覆盖所有岛屿的最小数量的雷达装置。注意,岛的位置由其xy坐标表示。
图A雷达装置的示例输入
输入
输入包含几个测试用例。每种情况的第一行包含两个整数n(1 <= n <= 1000)和d,其中n是海中岛屿的数量,d是雷达装置的覆盖距离。接下来是n行,每行包含两个整数,表示每个岛的位置坐标。然后是一个空白行来分隔案例。
输入由包含零对的行终止
产量
对于每个测试用例输出,一行包含测试用例编号,然后是所需的最少数量的雷达安装。“-1”安装意味着没有解决方案。
样本输入
<span style="color:#000000">3 2
1 2
-3 1
2 1
1 2
0 2
0 0
</span>
样本输出
<span style="color:#000000">案例1:2
案例2:1</span>
题目如上:
这个题首先需要对坐标进行排序,我刚开始因为没有排序而进行了无数次for和while导致了超时,,,o(╯□╰)o
这个题最著名的就是用贪心算法来算啦。
所谓的贪心算法,就是一个“贪”字。就是总是做出当前看来最优的选择,贪心算法不从整体去考虑,它做出的选择也是局部最优选择,从而达到全局优化选择。虽然贪心算法不一定能得到最优解,但是对很多问题,它是能够得到整体最优解的(譬如这道题)
贪心算法的基本思路就是:
从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到算法中的某一步不能再继续前进时,算法停止。
即:从问题的某一初始解出发;
求出可行解的一个解元素;
由所有解元素组合成问题的一个可行解;
关于贪心算法的例题,读者可移步:https://blog.csdn.net/ftl111/article/details/79707452
当小岛在雷达的最外边时,雷达覆盖的小岛是最多的。故此,先计算出以每个小岛为圆心,算出每个小岛与海岸的左右交点。
之后进行比较,有以下三种情况:
源码如下:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
struct COO
{
int x;
int y;
double x_r;
double x_l;
} coo[1100];
int comp(const COO &s1,const COO &s2)//自己定义的排序规则
{
return s1.x_l<s2.x_l;
}
int main()
{
int i,j,n,r,k=1,outcome=1;
scanf("%d%d",&n,&r);
while(r!=0&&n!=0)
{
for(i=0;i<n;i++)
{
scanf("%d%d",&coo[i].x,&coo[i].y);
if(coo[i].y>r||coo[i].y<0)
{
outcome++;
}
coo[i].x_l=coo[i].x-sqrt(r*r-coo[i].y*coo[i].y);
coo[i].x_r=coo[i].x+sqrt(r*r-coo[i].y*coo[i].y);
}
if(outcome!=1)
{
outcome=-1;
goto LOOP;
}
sort(coo,coo+n,comp);
for(i=1,j=0;i<n;i++)
{
if(coo[j].x_r>coo[i].x_r)
j=i;
if(coo[j].x_r<coo[i].x_l)
{
outcome++;
j=i;
}
}
LOOP:printf("Case %d: %d\n",k,outcome);
scanf("%d%d",&n,&r);
k++;
outcome=1;
}
return 0;
}
/*思路:
第1种.使用贪心算法
先是测出每座小岛以r为半径画圆与海岸线的左右交点
再从左往右,看右交点
判断三种情况
*/