问题描述
滑动积木块游戏的棋盘结构及某一种将牌的初始排列结构如图所示。
其中,B表示黑色将牌,W表示白色将牌,E表示空格。我们称将牌的排列结构称为格局,而根据单色将牌的个数,将游戏分别称为3滑块或4滑块游戏等。所以,上图就是3滑块游戏的初始格局。我们可以用字符串来代表格局,代表上图中初始格局的字符串为BBBWWWE。
游戏的规定走法是:
(1)任意一个将牌可以移入相邻的空格;
(2)任意一个将牌可相隔1个或2个其他的将牌跳入空格。
游戏要达到的目标是使所有白将牌都处在黑将牌的左边(左边有无空格均可),我们称为目标格局。很显然,3滑块游戏的目标格局共有7种。
随着将牌的移动,我们会得到一些中间格局,例如:
滑块游戏的某个中间格局
对于某个格局,通过一次移动滑块而得到的格局,称为其后继格局。我们需要找到某个中间格局的所有后继格局,即每种可能的走法所能得到的格局。
(2)输入
输入的第一行是一个整数N,表示共有N个格局。后续紧跟N行,每行由两部分构成,第一部分是一个整数n,表示这是一个n滑块游戏,第二部分是2n+1个字符,表示该游戏的某个格局。
(3)输出
首先判断输入的格局是否是目标格局,如果是,则输出“目标格局”后结束;如果不是目标格局,则按顺序(将格局看作字符串后,按照字典序排序,即B < E < W)输出该格局的所有后继格局。例如,BBEBWWW格局应该排在BBWBWEW格局的前面,因为在英文字母表中,第一个格局中的第3个字符E排在第二个格局的第3个字符W前面
(4)示例
输入
2
3 BBWBEWW
4 WWWWBBEBB
输出
结果_1
BBEBWWW
BBWBWEW
BBWBWWE
BBWEBWW
BEWBBWW
结果_2
目标格局
实验代码及运行结果
#include <iostream>
using namespace std;
int main() {
int i,j,N,empty,p,q,flag=1;
int n[2];
char temp;
char a[10][10];
char ai[10];
char aj[10];
cout << "请输入格局数:";
cin >> N;
for (j = 0; j < N; j++) {
cout << "输入滑块游戏模式(3/4):";
cin >> n[j];
cout << "滑块初始布局:";
for (i = 0; i < 2 * n[j] + 1; i++) {
cin >> a[j][i];
}
}
for (j = 0; j < N; j++) {
cout << "格局_" << j + 1 << endl;
for (i = 0; i < 2 * n[j] + 1; i++) {
if (a[j][i] == 'E')
empty = i;//找到空格位置
}
//判断是否为目标格局
for (i = 0; i < empty; i++) {
ai[i] = a[j][i];
}
for (i = empty; i < 2 * n[j]; i++) {
ai[i] = a[j][i + 1];
}
for (i = 0; i < n[j]; i++) {
if (ai[i] != 'W') {
flag = 0;
}
}
if (flag == 1)
cout << "目标格局"<<endl;
else if(flag==0)
{
for (i = empty - 3; i <= empty + 3; i++) {
if (i >= 0 && i < n[j] * 2 + 1 && i != empty) {
for (q = 0; q < 2 * n[j] + 1; q++) {
aj[q] = a[j][q];//将a[j][q]中的数据储存至aj[q]中
}
temp = aj[empty];
aj[empty] = aj[i];
aj[i] = temp;
for (p = 0; p < n[j] * 2 + 1; p++) {
cout << aj[p];
}
cout << endl;
}
}
}
}
cout << endl;
return 0;
}