poj1328解题报告.

摘要:网上的算法都是贪心算法,但是很少有人说明一下为什么可以用贪心算法,现在来分析一下这个题目.首先本题是要找雷达的数量,可以很容易的想到雷达的可能位置由小岛确定,以小岛为圆心画圆就可以确定两个在x轴上的交点.

【1】雷达的位置占据了一个区间,这本质上就是一个活动安排问题.因为冲突的活动(区间)代表这只要把一个雷达放在相交的区间就可以满足小岛的覆盖).所以问题转化为寻找不相交雷达的最大集合的数量.

【2】有一个细节需要注意,当我们寻找下一个不相交区间时,要注意更新上一个区间(改变判断标准).


#include "stdafx.h"
#include "iostream"
#include<algorithm>
#include "cmath"
using namespace std;
double bound1[1000],bound2[1000];
int coorx[1000], coory[1000];

bool compute(int x,int y,int d,double &result1,double &result2)
{
    if((d*d- y*y < 0)||(y<0))
        return false;
    else 
    {
        result1 = x - sqrt(double(d*d) - double(y*y));
        result2 = x + sqrt(double(d*d) - double(y*y));
        return true;
    }
}

int Find(int n,int d)
{
    double result1,result2;
    int count1 = 0,count2 = 0;
    int number = 0;
     return number;
}

void sort(int N)//插入排序,从大到小
{
    int i,j;
    for(i = 1;i<=N-1;i++)
    {
        double temp = bound1[i]; 
        double temp2 = bound2[i];
        for(j = i;j>0&&bound1[j-1]>temp;j--)
        {
         bound1[j] = bound1[j-1];
          bound2[j] = bound2[j-1];
        }
        bound1[j] = temp;
         bound2[j] = temp2;
    }
}


int main()
{
    int n,d,count,count2 = 0;
    double result1,result2;
    bool check;
    while(1)
    {
        count2++;
        cin>>n;
        cin>>d;
        if(n==0&&d==0)
            break;
        count = n;
        check = true;
        memset(bound1,-100,sizeof(bound1));
        memset(bound2,100,sizeof(bound2));
        while(count--)
        {
            cin >> coorx[count];
            cin >>  coory[count];
            if(compute(coorx[count],coory[count],d,result1,result2))
            {
                bound1[count] = result1;
                bound2[count] = result2;
            }
            else
                 check = false;
        } 
     sort(n);//对雷达区间排序
    int num = 0;  
    double right = -1;  
    for(int i=0;i<n;i++)
    {                        
        if(i==0)
        {  
            num++;   
            right = bound2[i];          
        }
        else
        {                 
            if(bound1[i] <= right)//有重叠
            {        
                  if(bound2[i]<right)
                     right = bound2[i];                       
                  continue;                              
            }
            else//没有重叠
            {  
                  num++;  
                  right = bound2[i];        
            }  
        }  
    }   
    if(d >= 0&&check==true)
    cout<<"Case "<<count2<<": "<<   num<<endl;
    else
    cout<<"Case "<<count2<<": "<<-1<<endl;
    }
    return 0;
}

你可能感兴趣的:(poj1328解题报告.)