一道挺经典的贪心。每个点可以在x轴覆盖一个区间,然后按x从小到大排序 , 找重叠区域即可。
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <cstring> #include <map> #include <string> #include <stack> #include <cctype> #include <vector> #include <queue> #include <set> #include <utility> #include <cassert> using namespace std; ///#define Online_Judge #define outstars cout << "***********************" << endl; #define clr(a,b) memset(a,b,sizeof(a)) #define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 #define mk make_pair #define FOR(i , x , n) for(int i = (x) ; i < (n) ; i++) #define FORR(i , x , n) for(int i = (x) ; i <= (n) ; i++) #define REP(i , x , n) for(int i = (x) ; i > (n) ; i--) #define REPP(i ,x , n) for(int i = (x) ; i >= (n) ; i--) const int MAXN = 1000 + 50; const int sigma_size = 26; const long long LLMAX = 0x7fffffffffffffffLL; const long long LLMIN = 0x8000000000000000LL; const int INF = 0x7fffffff; const int IMIN = 0x80000000; #define eps 1e-8 const int MOD = (int)1e9 + 7; typedef long long LL; const double PI = acos(-1.0); typedef double D; typedef pair<int , int> pi; ///#pragma comment(linker, "/STACK:102400000,102400000") struct Point { D x , y; }a[MAXN]; bool cmp(Point a , Point b) { return a.x < b.x; } int main() { // freopen("heritage.in","r",stdin); // freopen("heritage.out","w",stdout); int n , d; int kase = 1; while(~scanf("%d%d" , &n , &d)&&(n || d)) { printf("Case %d: " , kase++); int ok = 1; FOR(i , 0 , n) { int xxx , yyy; scanf("%d%d" , &xxx , &yyy); if(abs(yyy) > d)ok = 0; a[i].x = xxx * 1.000 - sqrt(d * d * 1.000 - yyy * yyy * 1.000); a[i].y = xxx * 1.000 + sqrt(d * d * 1.000 - yyy * yyy * 1.000); } if(!ok)printf("-1\n"); else { sort(a , a + n , cmp); int cnt = 1; D tmp = a[0].y; FOR(i , 1, n) { if(a[i].y < tmp) { tmp = a[i].y; } else if(a[i].x > tmp) { cnt++; tmp = a[i].y; } } printf("%d\n" , cnt); } } return 0; }