【基础排序】USACO Bronze 2016 January - Angry Cows

文章目录

题目描述

奶牛 Bessie 设计了一款她认为会成为下一个热门的电子游戏------《愤怒的奶牛(Angry Cows)》

游戏的设定是:玩家用弹弓将一头奶牛射向一条 一维数轴 上的干草堆。如果奶牛落在某个干草堆上,这个干草堆会爆炸,并可能引发连锁反应,使附近的干草堆也接连爆炸。

目标是:只用一头奶牛,引爆尽可能多的干草堆。

数轴上有 N N N 个干草堆,分别位于 互不相同的整数位置 : x 1 , x 2 , ... , x N x_1, x_2, \dots, x_N x1,x2,...,xN

爆炸规则如下:

  • 如果奶牛被发射到位置为 x x x 的干草堆上:

    • 在时间 t = 1 t=1 t=1,该干草堆爆炸,爆炸半径为 1 1 1
    • 所有与 x x x 的距离不超过 1 1 1 的干草堆都会被波及
  • 被波及的干草堆会在 下一时刻( t = 2 t=2 t=2)同时爆炸

    • 每个爆炸半径为 2 2 2
    • 可以继续波及距离不超过 2 2 2 的尚未爆炸干草堆
  • 接下来:

    • 在时间 t = 3 t=3 t=3,爆炸半径变为 3 3 3
    • 依此类推
  • 一般地:

    • 在时间 t t t 爆炸的干草堆,其爆炸半径为 t t t
    • 被波及的干草堆会在 t + 1 t+1 t+1 时刻爆炸

输入格式

第一行一个整数 N N N( 1 ≤ N ≤ 100 1 \le N \le 100 1≤N≤100)。

接下来 N N N 行,每行一个整数 x i x_i xi,表示第 i i i 个干草堆的位置 0 ≤ x i ≤ 10 9 0 \le x_i \le 10^9 0≤xi≤109。

输出格式

输出一个整数,表示 一头奶牛最多可以引爆的干草堆数量

样例输入

cpp 复制代码
6
8
5
6
13
3
4

样例输出

cpp 复制代码
5

样例解释

如果把奶牛发射到 位置 5 5 5 的干草堆上:

  • 时间 t = 1 t=1 t=1(半径 1 1 1): 引爆位置 4 4 4 和 6 6 6 的干草堆

  • 时间 t = 2 t=2 t=2(半径 2 2 2): 这些爆炸又引爆了位置 3 3 3 和 8 8 8

  • 时间 t = 3 t=3 t=3(半径 3 3 3): 爆炸范围不足以波及位置 13 13 13

最终一共爆炸了 5 5 5 个干草堆

提交链接

Angry Cows

思路分析

总结 🧠✨

本题的关键在于认识到:爆炸只沿数轴向左右传播,且左右互不影响。因此,可以将问题拆分为------从某个起点开始,分别计算向左和向右最多能引爆多少干草堆。

对于单一方向的爆炸过程,采用模拟 + 贪心推进 的方式:爆炸半径从 1 1 1 开始逐轮增大,在每一轮中尽可能向当前方向推进到最远能被覆盖的干草堆;一旦无法继续推进,连锁反应结束。

由于数据规模很小( N ≤ 100 N≤100 N≤100),直接枚举每一个干草堆作为起点,分别计算左右扩展范围,取最大值即可 。整体时间复杂度为 O ( n 2 ) O(n^2) O(n2)。

定义move(pos, dir) 来模拟从第 p o s pos pos 个干草堆开始,沿着 d i r dir dir 方向( − 1 -1 −1 表示向左, 1 1 1 表示向右)发生的连锁爆炸。

🧩在单个方向的模拟中:

  1. 从起点开始,爆炸半径 s s s 设为 1 1 1

  2. 在当前半径 s s s 内,不断向同一方向推进,只要下一个干草堆与当前爆炸点的距离不超过 s s s,就可以被引爆

    cpp 复制代码
    while(next + dir >= 1 && next + dir <= n && abs(x[next + dir] - x[now]) <= s)
        next += dir;
  3. 若某一轮无法再向前推进,说明该方向的连锁反应结束

  4. 最终用下标差值表示该方向上被引爆的干草堆数量

参考代码

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e2 + 9;

int n , x[maxn];

int move(int pos , int dir)  //当前点的下标  移动的方向
{
    int now = pos , s = 1;   //当前的位置  燃烧的半径

    while(1)
    {
        int next = now;
        while(next + dir >= 1 && next + dir <= n && abs(x[next + dir] - x[now]) <= s)
            next += dir;

        if(next == now)  //原地不动
            break;

        now = next;
        s++;
    }
    return abs(pos - now);

}
int main()
{
    freopen("angry.in" , "r" , stdin);
    freopen("angry.out" , "w" , stdout);

    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> x[i];
    sort(x + 1 , x + 1 + n);    //每一个点的坐标

    int mx = 0;

    for(int i = 1; i <= n; i++)
    {
        mx = max(mx , move(i , -1) + move(i , 1) + 1);
    }
    cout << mx;
    return 0;
}
相关推荐
君义_noip7 小时前
信息学奥赛一本通 2134:【25CSPS提高组】道路修复 | 洛谷 P14362 [CSP-S 2025] 道路修复
c++·算法·图论·信息学奥赛·csp-s
仍然.12 小时前
JavaDataStructure---排序
数据结构·算法·排序算法
小芒果_0118 小时前
P8662 [蓝桥杯 2018 省 AB] 全球变暖
c++·算法·蓝桥杯·信息学奥赛
曹自标18 小时前
workflow 拓扑排序算法
windows·算法·排序算法
梅川_酷子1 天前
JavaScript算法 - 冒泡排序
排序算法
星火开发设计2 天前
堆排序原理与C++实现详解
java·数据结构·c++·学习·算法·排序算法
星火开发设计2 天前
折半插入排序原理与C++实现详解
java·数据结构·c++·学习·算法·排序算法·知识
君义_noip2 天前
【模板:矩阵加速递推】信息学奥赛一本通 1642:【例 2】Fibonacci 第 n 项
c++·线性代数·矩阵·信息学奥赛·csp-s
君义_noip3 天前
信息学奥赛一本通 1644:【例 4】佳佳的 Fibonacci
c++·数论·信息学奥赛·csp-s