题目描述
直线上有N个点,点i的位置是点Xi,从这N个点中选择若干个,给他们加上标记。对于每一个点,其距离为R以内的区域里必须有带标记的点自己本身带标记的点,可以认为与其距离为0的地方有一个带标记的点。求被标记的点最少个数是多少。
限制条件
1 =< N <= 1000
0 =< R <= 1000
0 =< Xi <= 1000
Input
第一行:半径R 点的个数N
第二行:点的位置Xi
当R N 都为 -1时,结束输入
Output
输出最少被标记的点的个数
Sample Input
0 3
10 20 20
10 7
70 30 1 7 15 20 50
-1 -1
Sample Output
2
4
解题思路
我们从最左边的点开始考虑,那么哪个点被标记呢? 答案是从最左边的点开始,距离为R以内的最远的点被标记。
先贪一个半径,然后再贪另一个半径,这样就可以将这个半径范围完美地表达出来了。
import java.util.Arrays;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
int R = sc.nextInt();
int n = sc.nextInt();
if(R == -1 && n == -1) {
break;
}
int[] a = new int[n];
for(int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
Arrays.sort(a); //排序
int k = 0;
int count = 0;
while(k < n) {
//x是没有被覆盖的最左边的点的位置
int x = a[k++];
//一直向右前进直到距x的距离大于R的点
while(k < n && a[k] <= R + x) k++;
//y是需要被标记点的位置(圆的中心)
int y = a[--k];
//一直向右前进直到距y的距离大于R的点
while(k < n && a[k] <= R + y) k++;
count++;
}
System.out.println(count);
}
}
}