「NOIP2015」跳石头题解

题目描述:

        一年一度的“跳石头”比赛又要开始了!

        这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有n  块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。

        为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走m  块岩石(不能移走起点和终点的岩石)。

 输入格式:

        输入文件第一行包含三个整数 ,分别表示起点到终点的距离,起点和终点之间的岩石数,以及组委会至多移走的岩石数。

        接下来 n 行,每行一个整数,第 i 行的整数 d[i](0 < d[i] < l)表示第 i 块岩石与起点的距离。这些岩石按与起点距离从小到大的顺序给出,且不会有两个岩石出现在同 一个位置。

输出格式:

        输出文件只包含一个整数,即最短跳跃距离的最大值。    

样例
样例输入
复制25 5 2 
2
11
14
17 
21
样例输出
复制4

   

数据范围与提示

对于 20% 的数据,0<=n<=m<=10。int check(int p) {
    int b = 0, c = 0;
    for (int i = 1; i <= n; i++) {
        if (a[i] - c < p)
            b++;
        else
            c = a[i];
    }
    return b;
}
对于 50% 的数据,0<=m<=n<=100。
对于 100% 的数据,0 <=m<=n<=50000,1<=L<=1000000000。

解法如下:

首先,暴力只能的50分。

所以,只能用二分算法去找答案。                                        *所有二分都是枚举答案!!!

二分算法(也叫分治算法)原理由下👇

现在联系到此题,枚举最短跳跃的距离最大值。

来写check():

 

int check(int p) {
    int b = 0, c = 0;        //b是要移走的块数
    for (int i = 1; i <= n; i++) {
        if (a[i] - c < p)                //判断如果距离不够,需移走的块数加1
            b++;
        else
            c = a[i];
    }
    return b;
}

再加上输入输出:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

LL n, m, l;
LL a[50010];

int check(int p) {
	int b = 0, c = 0;
	for (int i = 1; i <= n; i++) {
		if (a[i] - c < p)
			b++;
		else
			c = a[i];
	}
	return b;
}

int main() {
	scanf("%d%d%d", &l, &n, &m);    //输入
	for (int i = 1; i <= n; i++) {
		scanf("%d", a + i);
	}
	LL le = 0, ri = l;				//设置左右端点
	while (ri > le) {//如果没找到答案,就继续找,直到le > ri为止
		LL mid = (ri + le + 1) >> 1;   //求中间值
		if (check(mid) <= m) {
			le = mid;
		} else {
			ri = mid - 1;
		}
	}
	printf("%d", le);
	return 0;
}
运行一下样例:

再提交一下:

显示分类标签
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!对于扫雷游戏的题解,我可以给你一些思路和代码示例。首先,你需要了解扫雷游戏的规则和要求。接下来,你可以使用C++语言来实现游戏逻辑和界面。 下面是一个简单的扫雷游戏的C++代码示例: ```cpp #include <iostream> #include <vector> #include <random> using namespace std; class MinesweeperGame { private: int rows; int cols; vector<vector<char>> board; vector<vector<bool>> revealed; vector<pair<int, int>> directions = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}; public: MinesweeperGame(int m, int n, int mineCount) { rows = m; cols = n; board.resize(rows, vector<char>(cols, ' ')); revealed.resize(rows, vector<bool>(cols, false)); placeMines(mineCount); calculateNumbers(); } void printBoard() { cout << " "; for (int j = 0; j < cols; j++) { cout << j << " "; } cout << endl; for (int i = 0; i < rows; i++) { cout << i << " |"; for (int j = 0; j < cols; j++) { cout << board[i][j] << "|"; } cout << endl; } } bool isGameOver() { for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (board[i][j] == 'M' && revealed[i][j]) { return true; } } } return false; } void reveal(int row, int col) { if (row < 0 || row >= rows || col < 0 || col >= cols || revealed[row][col]) { return; } revealed[row][col] = true; if (board[row][col] == 'M') { return; } if (board[row][col] == '0') { for (auto dir : directions) { reveal(row + dir.first, col + dir.second); } } } private: void placeMines(int mineCount) { random_device rd; mt1

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值