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; }