POJ - 3069 Saruman‘s Army
发布日期:2021-05-20 04:56:44 浏览次数:21 分类:精选文章

本文共 1091 字,大约阅读时间需要 3 分钟。

为了解决这个问题,我们需要找到最少的标记点,使得每个点标记后能够覆盖前面和后面距离r以内的点。通过贪心算法,我们可以实现这一目标。

方法思路

  • 排序点:将所有点按照从小到大的顺序排列。
  • 贪心选择:从第一个点开始,标记该点并尽可能覆盖后续的点。
  • 扩展范围:对于每个标记点,找到能够覆盖的最远点,然后将标记点移动到下一个未被覆盖的点。
  • 递归覆盖:重复上述过程,直到所有点都被覆盖。
  • 这种方法确保每次标记点覆盖尽可能多的后续点,减少了总标记次数。

    解决代码

    #include 
    #include
    using namespace std;int main() { const int N = 100010; int n, r; while (cin >> r >> n) { if (r == -1) break; int a[N]; for (int i = 0; i < n; ++i) { cin >> a[i]; } sort(a, a + n); int ans = 0; int i = 0; while (i < n) { int p = a[i]; i++; while (i < n && a[i] - p <= r) { i++; } ans++; int x = a[i-1]; while (i < n && a[i] <= x + r) { i++; } } cout << ans << endl; } return 0;}

    代码解释

  • 输入处理:读取输入数据,包括每个测试用例的r值和点数n以及点的具体值。
  • 排序点:将点按照从小到大的顺序排列,以便后续处理。
  • 标记遍历:使用双层循环处理每个点,外层循环处理每个标记点,内层循环扩展标记点的覆盖范围。
  • 覆盖扩展:对于每个标记点,找到能覆盖的最远点,移动标记点到下一个未被覆盖的点,递增标记次数。
  • 输出结果:在每个测试用例结束后,输出所需的最少标记次数。
  • 这种方法确保了每个标记点覆盖尽可能多的后续点,从而得到最小的标记次数,确保高效性和正确性。

    上一篇:ajax请求的步骤
    下一篇:POJ - 3617 Best Cow Line

    发表评论

    最新留言

    网站不错 人气很旺了 加油
    [***.192.178.218]2025年04月10日 23时44分15秒