POJ - 3069 Saruman's Army

题目链接

题目描述

直线上有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);
		}
		
	}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值