码题杯 小码哥的跳棋游戏 题型:模拟 细节

119 阅读2分钟

码题集OJ-小码哥的跳棋游戏 (matiji.net)

小码哥喜爱跳棋。跳棋游戏在一条直线上,一共n个位置(1~n),每个位置有2个状态:0表示没有棋子,1表示有棋子。小码哥的棋子自然是能通过没有棋子的位置。当面前有1个棋子时,小码哥可以直接跳过。当有两个及以上棋子连在一起时,小码哥的棋子是跳不过去的。这时候,就要花费能量,破坏掉一些棋子,才能跳过。已知破坏一枚棋子需要花费一点能量。小码哥的棋子从第0个位置出发,现在要求小码哥到达终点(第n个位置)至少需要花费多少能量?

格式

输入:

5
0 1 1 0 0

样例输出:

1

思想

刚开始这样写只过了9个点:

#include <bits/stdc++.h>
#define int long long
using namespace std;
int n;
const int N = 1e5 + 10;
int a[N];
int cnt;

signed main() {
	cin.tie(nullptr)->sync_with_stdio(0);
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> a[i];

	for (int i = 0; i < n; i++) {
		if (a[i] == 1 && a[i + 1] == 1)
			a[i + 1] = 0, cnt++;
	}
//	for (int i = 0; i < n; i++)
//		cout << a[i] << " ";

	cout << cnt;

	return 0;
}

image.png

原因是目标点也是"1"的状态,那么目标点也要被破坏。但是因为条件是a[i]==1&&a[i+1]==1,目标点之后就没有a[i+1]了,因此进不去条件。所以对于目标点我们需要特判一下。

特判如下,

#include <bits/stdc++.h>
#define int long long
using namespace std;
int n;
const int N = 1e5 + 10;
int a[N];
int cnt;

signed main() {
	cin.tie(nullptr)->sync_with_stdio(0);
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> a[i];

	for (int i = 0; i < n; i++) {
		if (a[i] == 1 && a[i + 1] == 1)
			a[i + 1] = 0, cnt++;
	}
//	for (int i = 0; i < n; i++)
//		cout << a[i] << " ";
    cnt+=a[n-1];
	cout << cnt;

	return 0;
}

image.png

我刚开始只是统计要破坏点的个数,并没有实际去修改棋子的状态,结果一个都没过:

#include <bits/stdc++.h>
#define int long long
using namespace std;
int n;
const int N = 1e5 + 10;
int a[N];
int cnt;

signed main() {
	cin.tie(nullptr)->sync_with_stdio(0);
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> a[i];

	for (int i = 0; i < n; i++) {
		if (a[i] == 1 && a[i + 1] == 1)
		cnt++;
	}
//	for (int i = 0; i < n; i++)
//		cout << a[i] << " ";
	cout << cnt;

	return 0;
}

image.png

原因很明显,当有一段连续的1111时,当a[i]=1,a[i+1]=1,cnt++,此时若不修改a[i+1]的值为0,那么当i走到了i+1的位置时,此时a[i+1]应该为0的,但是因为我们没有修改其值,因此会导致我们错误判断,对结果差生错误。