Djhnj. 转珠游戏
时间限制:200ms 内存限制:64.0MB 代码提交间隔:1分钟(现在可以提交)
试题来源:rookiepig
问题描述
转珠游戏是这样一种消除类的游戏,给定一个大小为 行 列的棋盘格,每个棋盘格中都放了一个珠子,珠子有颜色,游戏的方法是通过交换相邻两个珠子使得颜色相同的珠子连在一起,当颜色相同的珠子满足特定条件时就可以消除,消除的珠子越多得分越高。注意每个珠子都受重力影响,即如果消除后某个珠子下方没有珠子,该珠子会掉落,直到有珠子在其下方。
玩家进入游戏就会看到不同颜色的珠子放在格子中,举例如下:
115000
221000
332000
443000
554000
Data
其中数字 0 比较特殊,表示没有珠子,数字 1-6 表示 6 种不同颜色珠子。
玩家要选择一个珠子开始,这里选择位于第 行 列颜色为 的珠子开始,然后玩家连续进行 次向下交换的转珠,整个过程相当于在第三列上从上到下进行了 次相邻的交换(可以想象成第一行 这个珠子向下走到了最后一行,通过交换的方式走下去),那么棋盘会变成:
111000
222000
333000
444000
555000
玩家结束转珠后,开始进行消除。消除的规则是:从任何一个珠子开始沿着上、下、左、右四个方向之一有至少3个相同颜色的珠子连续即可全部消除该方向上的连续同色珠子。
所以上述玩家操作后,每行 个相连的珠子均可消除,消除后棋盘变为:
000000
000000
000000
000000
000000
现在给你一个开始的棋盘格状态,玩家开始转珠的起手位置,以及玩家中间一系列的移动操作,请你输出玩家结束操作并进行 1次 消除后棋盘的状态。
输入格式
首先输入棋盘的初始状态,共 行,每行为一个长度为 的字符串,保证字符串中只有数字字符 0-6;
接下来一行两个整数 ,中间用空格分开表示玩家从 行 列开始转珠。
最后有一行字符串,每个字符只能是 U, D, L, R(依次代表上、下、左、右)的一种,表示玩家一次转珠的方向,所以字符串的长度就是玩家转珠操作的步数。
输出格式
输出也是 行每行一个长度为 的字符串,表示经过玩家的转珠操作和 1次 消除后棋盘的状态。
样例输入1
115000
221000
332000
443000
554000
1 3
DDDD
样例输出1
000000
000000
000000
000000
000000
样例解释:见题目描述
样例输入2
000000
000000
000000
001100
323310
5 2
L
样例输出2
000000
000000
000000
000000
201110
样例解释:注意因为只允许发生一次消除,交换后最后一行的 333 消除后珠子掉落下来形成的 111 不会再次消除。
样例输入3
000000
000000
124542
653446
123456
4 3
URR
样例输出3
000000
000000
120002
655036
123056
样例解释:经过移动后版面为:
000000
000000
125432
654446
123456
4形成了十字形状,从中心的 4 看上下和左右都满足3个以上相连,所以整个十字消除。
样例输入4
100000
100000
210000
130000
114100
3 1
RDRDR
样例输出4
000000
000000
000000
000000
034200
样例解释:经过移动后版面为:
100000
100000
130000
104000
111200
左下角的 1 形成了L字形状,从左下角的 1 看上方和右方都满足3个以上相连,所以整个L字消除。
评测用例规模与约定
所有数据,保证起手位置和操作序列均合法,操作序列长度小于 ;不同测试点满足不同的性质:
测试点 性质
1 不会发生消除
2 只有 3 个相连的消除,消除后不会掉落
3 只有 3 个相连的消除
4 只有单独横向或者单独纵向的消除
5 只有十字消除
6 只有L字消除
7-10 没有任何限制
我用暴力尝试过了,写了好几百行,有点崩溃了,求各位帮给蒟蒻讲讲思路,给给代码。
下面的代码由AI生成,无法确定正确性,仅供参考:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 交换两个珠子的位置
void swap_beads(vector<vector<char>>& beads, int x1, int y1, int x2, int y2) {
swap(beads[x1][y1], beads[x2][y2]);
}
// 在当前位置上下左右四个方向查找相同颜色的珠子
void dfs(vector<vector<char>>& beads, vector<vector<bool>>& visited, int x, int y) {
if (x < 0 || x >= beads.size() || y < 0 || y >= beads[0].size() || visited[x][y]) {
return;
}
visited[x][y] = true;
char color = beads[x][y];
int count = 1;
// 向上查找
int i = x - 1;
while (i >= 0 && beads[i][y] == color) {
visited[i][y] = true;
count++;
i--;
}
// 向下查找
i = x + 1;
while (i < beads.size() && beads[i][y] == color) {
visited[i][y] = true;
count++;
i++;
}
// 向左查找
int j = y - 1;
while (j >= 0 && beads[x][j] == color) {
visited[x][j] = true;
count++;
j--;
}
// 向右查找
j = y + 1;
while (j < beads[0].size() && beads[x][j] == color) {
visited[x][j] = true;
count++;
j++;
}
// 如果有三个或以上相连的珠子,则将它们标记为空格
if (count >= 3) {
beads[x][y] = '0';
}
// 递归标记上下左右四个方向的珠子
if (x - 1 >= 0 && beads[x - 1][y] == color) {
dfs(beads, visited, x - 1, y);
}
if (x + 1 < beads.size() && beads[x + 1][y] == color) {
dfs(beads, visited, x + 1, y);
}
if (y - 1 >= 0 && beads[x][y - 1] == color) {
dfs(beads, visited, x, y - 1);
}
if (y + 1 < beads[0].size() && beads[x][y + 1] == color) {
dfs(beads, visited, x, y + 1);
}
}
// 消除珠子
void remove_beads(vector<vector<char>>& beads) {
vector<vector<bool>> visited(beads.size(), vector<bool>(beads[0].size(), false));
// 遍历所有珠子并进行消除
for (int i = 0; i < beads.size(); i++) {
for (int j = 0; j < beads[0].size(); j++) {
if (!visited[i][j] && beads[i][j] != '0') {
dfs(beads, visited, i, j);
}
}
}
// 重新排列珠子,使得消除的空位填充
for (int j = 0; j < beads[0].size(); j++) {
int idx = beads.size() - 1;
for (int i = beads.size() - 1; i >= 0; i--) {
if (beads[i][j] != '0') {
beads[idx][j] = beads[i][j];
if (idx != i) {
beads[i][j] = '0';
}
idx--;
}
}
}
}
int main() {
int n, m, k;
cin >> n >> m >> k;
vector<vector<char>> beads(n, vector<char>(m));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> beads[i][j];
}
}
for (int i = 0; i < k; i++) {
int x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
swap_beads(beads, x1, y1, x2, y2);
}
remove_beads(beads);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cout << beads[i][j];
}
cout << endl;
}
return 0;
}