题意:给出岛屿个数n和地雷的范围c,然后再给出n个岛屿的xy坐标,在x轴上放置地雷,求出能覆盖所有岛屿的地雷最小数
否则输出-1
思路:1、一开始,我第一个想法就是对岛屿进行排序,x从小到大,接着在x轴上放置地雷,尽可能靠右边并且能够覆盖左边的岛屿
,接着筛选右边同时也处于该地雷之内的岛屿,再不断找左边第一个没有地雷覆盖的岛屿继续放置最右边的地雷。。。
然后WA了。
2、网上的普遍做法,就是对每个岛屿计算能够覆盖到他的地雷范围,然后题目就变成区间的最少覆盖问题了,我就用这种
算法做了,最终还是AC了。
AC代码:
#include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <iostream> using namespace std; const int MAX_N = 1005; int n, _case,d; double u,v; bool vis[MAX_N]; struct node{ double x,y; }w[MAX_N]; int cmp(node n1, node n2) { if(n1.x == n2.x) return n1.y > n2.y; else return n1.x < n2.x; } void solve() { sort(w,w+n, cmp); /// for(int i = 0; i < n; i++) // cout<<w[i].x<<' '<<w[i].y<<endl; int ans = 1; double right = w[0].y; for(int i = 1; i < n; i++) { if(w[i].x > right) { ans ++; right = w[i].y; }else { if(w[i].y < right) right = w[i].y; } } printf("%d ", ans); } int main() { //freopen("in.txt", "r", stdin); _case = 1; while(cin>>n>>d && (n || d)) { bool flag = false; for(int i = 0; i < n; i++) { scanf("%lf %lf", &u, &v); //cin>>u>>v; double dist = sqrt(1.0*d*d - v*v); w[i].x = u - dist; w[i].y = u + dist; if(fabs(v) > d) flag = true; } printf("Case %d: ", _case++); if(flag) puts("-1"); else solve(); } return 0; }