C++-跳石头 解题思路
作者:互联网
【Horn Studio】编程专栏: 抢气球 解题思路
题目
题目描述
一年一度的“跳石头”比赛又要开始了!这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有NN块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。
为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走MM块岩石(不能移走起点和终点的岩石)。
输入
第一行包含三个整数L,M,NL,M,N,分别表示起点到终点的距离,起点和终点之间的岩石数,以及组委会最多移走的岩石数。保证L≥1L≥1且N≥M≥0N≥M≥0 。接下来NN行,每行一个整数,第ii行的整数DiDi,表示第ii块岩石与起点的距离。这些岩石按与起点距离从小到大的顺序给出,且不会有两个出现在同一个位置。
输出
一个整数,即最短跳跃距离的最大值。样例输入 复制
25 5 2
2
11
14
17
21
样例输出 复制
4
提示
对于20%的数据,0≤M≤N≤100≤M≤N≤10
对于50%的数据,
0≤M≤N≤1000≤M≤N≤100
对于100%的数据,
0≤M≤N≤50,000,1≤L≤1,000,000,00000≤M≤N≤50,000,1≤L≤1,000,000,0000
来源
思路
这道题跟二分一样,从起点出发,先选定一段距离mid,若前面的石头B与你所站着的石头A的距离小于mid,就把B搬掉,记录一下;如果不,就把B留下,再跳到石头B上。照这个步骤多次循环后,如果搬掉的石头多了,就把距离mid定小点;如果少了,就把mid定大点。,很简单。直接考虑问题比较困难。我们首先考虑另一个问题,如果给定一个距离d,问至少要移走多少石头才能满足石头之间的最小距离不小于d?对于这个问题,答案就很简单了。从左岸开始,移走它小于d的所有石头,再往后跳一步,循环往复。就解决了!
我们同样需要一个判断,大概就是如下:
bool check(int x)
{
int last = 0, cnt = 0;
for (int i = 1; i <= n; i++) {
if (a[i] - last < x)
cnt++;
else
last = a[i];
}
if (cnt > m)
return false;
return true;
}
代码
#include <bits/stdc++.h>
using namespace std;
int a[50010], n, m, L, ans;
bool check(int x)
{
int last = 0, cnt = 0;
for (int i = 1; i <= n; i++) {
if (a[i] - last < x)
cnt++;
else
last = a[i];
}
if (cnt > m)
return false;
return true;
}
int main()
{
cin >> L >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
a[n + 1] = L;
int l = 0, r = L;
while (l <= r) {
int mid = (l + r) / 2;
if (check(mid)) {
ans = mid;
l = mid + 1;
} else
r = mid - 1;
}
cout << ans;
return 0;
}
彩蛋
……这是哪?
标签:移走,int,岩石,C++,解题,000,终点,思路,起点 来源: https://www.cnblogs.com/Kelwen/p/Horn_Studio_CodeBlock_Half_8_end.html