poj1328

  觉得自己的做法和网上的有点不同,所以发一下。首先这道题是用贪心算法的,但是我采用的判定值和网上的不太一样。我的思路是从左往右放雷达,采用了贪心选择值x(圆心的坐标),按这个值对岛屿排序。拍完序后从左边开始放雷达,放在岛屿队列中第一个岛屿的x点处,如果雷达能监控到岛屿序列中的下一个岛屿a,则跳过岛屿a,否则再为a放一个雷达,依此类推。

代码如下

#include <iostream>
using namespace std;
#include <math.h>

struct island
{
    int x;
    int y;
};

void quick_sort(island *islands,int start,int end,int d);
int partition(island *islands,int start,int end,int d);
bool smaller_than(island *is1,island *is2,int d);

void sort(island *islands,int n,int d)
{
    quick_sort(islands,0,n-1,d);
}

void quick_sort(island *islands,int start,int end,int d)
{
    if(start>=end) return;
    int mid=partition(islands,start,end,d);
    quick_sort(islands,start,mid-1,d);
    quick_sort(islands,mid+1,end,d);
}

int partition(island *islands,int start,int end,int d)
{
    int front,back,dir=0;
    island tis=islands[start];
    
    front=start;
    back=end;
    while(front<back)
    {
        if(dir==0)
        {
            if(!smaller_than(&tis,islands+back,d)){
                islands[front].x=islands[back].x;
                islands[front].y=islands[back].y;
                front++;
                dir=1;
            }
            else back--;
        }
        else 
        {
            if(smaller_than(&tis,islands+front,d)){
                islands[back].x=islands[front].x;
                islands[back].y=islands[front].y;
                back--;
                dir=0;
            }
            else front++;
        }
    }
    islands[front].x=tis.x;
    islands[front].y=tis.y;
    return front;
}

bool smaller_than(island *is1,island *is2,int d)
{
    double v1=is1->x+sqrt(double(d*d-is1->y*is1->y)),v2=is2->x+sqrt(double(d*d-is2->y*is2->y));
    return v1<v2;
}


int place_radar(island *islands,int n,int d)
{
    int i,counter=0;
    double rx,ry=0;
    i=0;
    while(i<n)
    {
        rx=islands[i].x+sqrt(double(d*d-islands[i].y*islands[i].y));
        counter++;
        i++;
        if(i>=n) break;
        while((rx-islands[i].x)*(rx-islands[i].x)+(ry-islands[i].y)*(ry-islands[i].y)<=d*d) 
        {
            i++;
            if(i>=n) break;
        }
    }
    return counter;
}

int main()
{
    //freopen("data.txt","r",stdin);

    int i,n,d,counter=1,result;

    cin>>n>>d;
    while(n!=0||d!=0)
    {
        island *islands=new island[n];
        for(i=0;i<n;i++) cin>>islands[i].x>>islands[i].y;

        bool flag=true;
        for(i=0;i<n;i++) if(islands[i].y>d) {flag=false; break;}
        if(d<0) flag=false;

        if(!flag) result =-1;
        else{
            sort(islands,n,d);
            result=place_radar(islands,n,d);        
        }

        cout<<"Case "<<counter<<": "<<result<<endl;
        delete []islands;
        counter++;
        cin>>n>>d;
    }


    return 0;
}

另一篇文章及测试数据:http://blog.csdn.net/qqhuxiao/article/details/7686568

 

posted @ 2013-09-20 21:35  浅井光一  阅读(1824)  评论(0编辑  收藏  举报