poj 1328 Radar Installation

 

  

这个题WA了几次,后来改成从左往右计算就AC了,至于为什么我只能从精度上解释,算圆心的如果是加比减要好,因为sqrt丢失精度,再去减就会丢失更大;

思路:我的跟你一些大牛的思路不一样,好多大牛都是以岛屿为圆心(那种算法比较简单),我刚开始没有这样写因为是自己想的,我是先求出圆心的位置(圆心),然后对圆心进行排序;

我们再把圆从左边往右边移,移到左边的点在圆上,这时在寻找在圆上的点;

View Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
using namespace std;
class Point
{
       public:
        double x,y,circle;
};
Point point[1024];
bool cmp( Point a ,Point b )
{
   if( a.circle == b.circle )
       return a.x < b.x;
   return a.circle < b.circle;    
}
double Distance( Point a, double c )
{
    return sqrt( ( a.x - c )*( a.x - c ) + a.y*a.y );    
}
void VisitPoint( Point point[] ,double c, int visit[],double d,int n )
{
       for( int i = 0 ; i < n ;i ++ )
       {
       if( visit[i] ==0 )
       {
           double dis = Distance( point[i] , c );
           if( dis <= d  )
           {
              visit[i] = 1;        
           }         
       }        
    }
}
int main(  )
{
    int n ,D,Case=1,visit[1024];
    double circle[1024];
    while( scanf( "%d %d",&n ,&D ),n||D )
    {
         double  d = (double)D;
         int flag = 0;
         for( int i = 0 ; i < n ; i ++ )
         {
            scanf( "%lf %lf",&point[i].x ,&point[i].y );           
            if( point[i].y > d ) flag  =1;
            else
            point[i].circle = point[i].x + sqrt( d*d - point[i].y*point[i].y );
            visit[i] = 0;    
         }    
         printf( "Case %d: ",Case++ );
         if( flag  ) printf( "-1\n" );
         else
         {
            sort( point , point + n , cmp );
            int sum = 0;
            for( int i = 0 ; i < n ; i ++ )
            {
        //        printf( "%lf\n",point[i].circle );
                if( visit[i]==0 )
                {
                    sum++;
                    visit[i] = 1;
                    VisitPoint( point , point[i].circle ,visit , d ,n);    
                }    
            }
            printf( "%d\n",sum );
         }
    } 
    //system( "pause" );
    return 0;
}

 

 这个算法是看了别人的思想在写的,这种思想更明了,更简洁;这里也是以岛屿为圆心,它与岸边的焦点代表雷达只有在这个区域才可以;我们就对最右边进行排序;

然后,再取最左边的点,如果他的最右边与下个点的最左边大则雷达可以建在这个公共区域,如果没有,这就要进行重新取点及最左边的点右边移动;

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
using namespace std;
class Point
{
   public:
		double left,right;	
};
bool cmp( Point a , Point b )
{
    return a.right < b.right;	
}
int main()
{
    int n , D,Case = 1;
    double x,y;
    Point point[1024];
	while( scanf( "%d %d",&n ,&D ),n||D )
	{
	     double  d = (double)D;
		 int flag = 0;
	     for( int i = 0 ; i < n ; i ++ )
		 {
		    scanf( "%lf %lf",&x ,&y );		   
			if( y > d ) flag  =1;
			else
			{
			double dis = sqrt( d*d -y*y );
			point[i].left = x - dis ;
			point[i].right = x + dis;
		    }
		 }
		  printf( "Case %d: ",Case++ );
		 if( flag  ) printf( "-1\n" );
		 else
		 {
		     sort( point , point + n , cmp );
			 int sum = 0,k = 0;
			 while( k < n )
			 {
			      sum++;
			      int t = k;
			      k++;
				  while( k < n && point[t].right >= point[k].left  )
				         k++;		
			 }	
			 printf( "%d\n",sum );	
		 }		
	}	
    return 0;	
}

  

posted @ 2012-06-28 22:10  wutaoKeen  阅读(175)  评论(0编辑  收藏  举报