文章目录
题目描述
奶牛 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 个干草堆。
提交链接
思路分析
总结 🧠✨
本题的关键在于认识到:爆炸只沿数轴向左右传播,且左右互不影响。因此,可以将问题拆分为------从某个起点开始,分别计算向左和向右最多能引爆多少干草堆。
对于单一方向的爆炸过程,采用模拟 + 贪心推进 的方式:爆炸半径从 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 表示向右)发生的连锁爆炸。
🧩在单个方向的模拟中:
-
从起点开始,爆炸半径 s s s 设为 1 1 1
-
在当前半径 s s s 内,不断向同一方向推进,只要下一个干草堆与当前爆炸点的距离不超过 s s s,就可以被引爆
cppwhile(next + dir >= 1 && next + dir <= n && abs(x[next + dir] - x[now]) <= s) next += dir; -
若某一轮无法再向前推进,说明该方向的连锁反应结束
-
最终用下标差值表示该方向上被引爆的干草堆数量
参考代码
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;
}