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;	

}

  

你可能感兴趣的:(Install)