POJ3069 - Saruman's Army

直线上有N个点,点i的位置是Xi。从这N个点中选择若干个点,给它们加上标记。对每个点,其距离R内的区域里必须有带有标记的点(自己本身带有标记的点,可以认为与其距离为0的地方有一个带有标记的点)。在满足这样的条件下,至少多少个点被加上标记。

从最左边的点开始,距离为R以内的最远的点,加上第一个标记后,剩下的部分也用同样的办法处理。对于添加了符号的点右侧相距超过R的下一个点,采用同样的方法找到其右侧R距离以内最远的点添加标记。在所有的点被覆盖之前不断的重复这一过程。

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 int N, R;
 6 int X[1200];
 7 
 8 void solve()
 9 {
10     sort(X, X+N);
11     int i = 0, ans = 0;
12 
13     while (i < N)
14     {
15         //s是没有被覆盖的最左的点的位置
16         int s = X[i++];
17         //一直向右前进直到距s的距离大于R的点
18         while (i < N && X[i] <= s+R) i++;
19         //p是新加上标记的点的位置
20         int p = X[i-1];
21         //一直向右前进直到距p的距离大于R的点
22         while (i < N && X[i] <= p+R) i++;
23         ans++;
24     }
25     cout << ans << endl;
26 }
27 
28 int main()
29 {
30     while (cin >> R >> N)
31     {
32         if (R == -1 && N == -1)
33             return -1;
34         for (int i = 0; i < N; i++)
35             cin >> X[i];
36         solve();
37     }
38     return 0;
39 }

 

posted @ 2014-09-30 20:30  bournet  阅读(183)  评论(0编辑  收藏  举报