思路:
参见AC_hell的Blog 。 贪心。如何贪心?我们首先把每个雷达换成点,把岛屿换成雷达,让岛屿reach out for雷达。 雷达建在海岸线即x轴 上,显然雷达应建在一些重叠的区域内。如何选取? 把每个岛屿形成的等大的圆与x轴 的两个交点记录为一个区间,只要有一个雷达建在这个区间里,那么这个岛屿就被照顾到。所以我们将所有的区间的L 从左到右排序,遍历所有的区间,若有重叠则 ans 不变,若没有则 ans+1 注意每次都要更新区间 。 不知道哪里错了。
WA代码:
#include <iostream>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
struct SEC
{
double l, r;
SEC ( double a= 0 , double b= 0 ) { l = a, r = b; }
friend bool operator > ( const SEC & a, const SEC & b)
{
a. l > b. l;
}
} ;
priority_queue< SEC , vector< SEC> , greater< SEC> > Q;
int n, d;
bool Imp;
int ans;
int cas = 0 ;
void init ( ) {
while ( ! Q. empty ( ) )
Q. pop ( ) ;
ans = 0 ;
Imp = false;
return ;
}
void AC ( ) {
while ( ! Q. empty ( ) ) {
SEC cur = Q. top ( ) ;
Q. pop ( ) ;
double l = cur. l;
double r = cur. r;
while ( ! Q. empty ( ) ) {
cur = Q. top ( ) ;
if ( cur. l < r) {
l = cur. l;
r = min ( r , cur. r) ;
Q. pop ( ) ;
}
else
break ;
}
ans++ ;
}
return ;
}
int main ( ) {
while ( true) {
init ( ) ;
cas++ ;
cin>> n>> d;
if ( n + d == 0 )
break ;
for ( int i= 1 ; i<= n; i++ ) {
int x, y;
cin>> x>> y;
if ( y > d)
Imp = true;
else
Q. push ( ( SEC) ( x- sqrt ( d* d - y* y) , x+ sqrt ( d* d - y* y) ) ) ;
}
if ( Imp) {
cout<< "Case " << cas<< ": " << - 1 << endl;
continue ;
}
AC ( ) ;
cout<< "Case " << cas<< ": " << ans<< endl;
}
return 0 ;
}