编程语言:Java
题目链接:http://poj.org/problem?id=1328
题解:将各个小岛的数据压缩在一条线上,然后就变成了至少需要几个点才能够覆盖所有的线段,先调库使数组以右端点的大小升序排列,然后就可以进行取点了。注意:①此处传入的比较方法不能够直接 return (int)(o1.end - o2.end),不然会WA;②之所以要取右端点就是因为在覆盖左边海岛的同时,要尽可能地覆盖右边的海岛。
结果:AC
import java.io.*;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Main {
static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) throws IOException {
int N = 1;
for (; ; ) {
int n = sc.nextInt();
int d = sc.nextInt();
if (n == 0 && d == 0) break;
island[] a = new island[n];
boolean flag = false;
for (int i = 0; i < n; i++) {
int x = sc.nextInt();
int y = sc.nextInt();
if (y > d) flag = true;
double det = Math.sqrt(d * d - y * y);
a[i] = new island(x - det, x + det);
}
if(flag)
out.println("Case " + N++ + ": -1");
else{
Arrays.sort(a, new Comparator<island>() {
@Override
public int compare(island o1, island o2) {
if(o1.r>o2.r)
return 1;
else
return -1;
}
});
double z = a[0].r;
int ans = 1;
for (int i = 1; i < n; i++) {
if (a[i].l > z) {
ans++;
z = a[i].r;
}
}
out.println("Case " + N++ + ": " + ans);
}
}
out.flush();
}
}
class island {
double l;
double r;
public island(double l, double r) {
this.l = l;
this.r = r;
}
}