【基础排序】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;
}
相关推荐
Suprman21 小时前
平面排版问题的数学建模与算法设计
算法·数学建模·排序算法·排版套料
重生之小比特21 小时前
【算法拾光】二分查找|在排序数组中查找元素的第一个和最后一个位置 + 搜索旋转排序数组
数据结构·算法·排序算法
YukiRinLL21 小时前
查找与排序算法:复杂度、稳定性
数据结构·算法·排序算法
suhan2 天前
【数据结构】六、图:4.图的遍历(深度优先算法DFS、广度优先算法BFS)
数据结构·算法·排序算法
suhan2 天前
【数据结构】六、图:3.十字链表、邻接多重表、边集数组
数据结构·算法·排序算法
HPtiger2 天前
交换类排序详解:冒泡排序与快速排序
数据结构·算法·排序算法
程序员爱钓鱼2 天前
Go 编程实战:Benchmark——基准测试、testing.B、benchmem、性能对比与代码优化实战
go·排序算法
Suprman3 天前
从 B/S 到 Electron:平面排版套料系统桌面版开发实战
javascript·平面·electron·排序算法
HPtiger6 天前
数据结构——选择排序
数据结构·算法·排序算法
丑梨数据6 天前
信创环境里跑文档工具:格式兼容与本地合规的几个坑
数据结构·人工智能·算法·决策树·排序算法