一、
思路:将所有点按x大小排序,然后一次找到一个x轴上的点,使得包含最小的岛屿的点,且雷达位置点x尽可能的大。依次查找到结束。
代码如下,测试了很多数据都ok,可提交照样是wrong,mark一下,后面继续改进。
#include<iostream>
#include<cmath>
using namespace std;
struct stu
{
int x;
int y;
}island[1001];
int comp(const void *a,const void *b)
{
stu* ta=(stu*)a;
stu* tb=(stu*)b;
return (ta->x-tb->x);
}
float distance(int ax,int ay,int bx,int by)
{
float m=(ax-bx)*(ax-bx)+(ay-by)*(ay-by);
return sqrt(m);
}
int main()
{
int i,j,k=0;
int ca_num,d,last_i;
cin>>ca_num>>d;
int x,y,count,no_flag=0;
while((ca_num!=0)||(d!=0))
{
k++;count=0;no_flag=0;
for(i=0;i<ca_num;i++)
{
cin>>x>>y;
island[i].x=x;
island[i].y=y;
}
qsort(island,ca_num,sizeof(stu),comp);
i=island[0].x;j=0;
while(i<=island[ca_num-1].x&&j<ca_num)
{
if(island[j].y>d)no_flag=1;
// last_i=i;
while((i<island[j].x)||distance(island[j].x,island[j].y,i,0)<=d)i++;
count++;j++;
while(distance(island[j].x,island[j].y,i-1,0)<=d&&j<=ca_num)j++;
if(island[j].x<island[i].x)
{
while(distance(island[j].x,island[j].y,--i,0)>d);
j++;
while(distance(island[j].x,island[j].y,i,0)<=d&&j<=ca_num)j++;
}
}
if(no_flag==1)count=-1;
printf("Case %d:%d\n",k,count);
cin>>ca_num>>d;
}
return 0;
}
二、改进
上述代码搁置了几天,仔细看了下,发现将雷达位置限制为了整数,并且在进行判断时,有一种情况不能很好的解决,放弃了此思路。
看了网上利用区间思想的贪心方法,基于此,写了一下算法AC的。
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
struct stu
{
float left;
float right;
}area[1001],temp;
bool comp(stu a,stu b)
{
return a.left<b.left;
}
int main()
{
int i;
int flag=0;
int n;float r;
int ca=0;
int count;
while(cin>>n>>r&&(n||r))
{
flag=0;
for(i=0;i<n;i++)
{
float a,b;
cin>>a>>b;
if(fabs(b)>r)flag=1;
else
{
area[i].left=a-sqrt(r*r-b*b);
area[i].right=a+sqrt(r*r-b*b);
}
}
cout<<"Case "<<++ca<<": ";
if(flag==1)
{
cout<<-1<<endl;
}
else
{
count=1;
sort(area,area+n,comp);
temp=area[0];
for(i=1;i<n;i++)
{
if(area[i].left>temp.right)
{
count++;
temp=area[i];
}
else if(area[i].right<temp.right)
temp=area[i];
}
cout<<count<<endl;
}
}
return 0;
}