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


浙公网安备 33010602011771号