2022年三国杀华容道程序+BFS算法
作者:互联网
2022年三国杀华容道程序+BFS算法
程序代码如下
#include <bits/stdc++.h>
using namespace std;
set< vector<int> > vis;
struct Move {
vector<int> now;
int id, dire; // dire 0 表示往上或往左 1 表示往下或往右
};
map< vector<int>, Move > path;
vector<int> s; // 起始状态 6 * 6 矩阵扁平化
queue< vector<int> > q;
int dire[20]; // 0 代表水平方向 1 代表垂直方向
int n, g; // 表示方块个数,g为目标块
int e(int x, int y) {
return x * 6 + y;
}
bool isend(vector<int> & map) { // 检查是否到终点
int x, y;
for(int i=0; i < 6; i++)
for(int j=0; j < 6; j++)
if(map[e(i,j)] == g) {
x = i; y = j;
}
if(dire[g]) {
return false;
}else {
for(int i=y; i < 6; i++)
if(map[e(x,i)] != 0 && map[e(x,i)] != g) return false;
}
return true;
}
bool check(int x, int y) { // 检查(x, y)是否合法
if(x < 0 || x >= 6 || y < 0 || y >= 6) return false;
return true;
}
vector<int> move(vector<int> map, int id, int dir) { // 讲地图map中编号为id的块按dir方向移动
int x, y;
for(int i=0; i < 6; i++)
for(int j=0; j < 6; j++)
if(map[e(i,j)] == id) {
x = i; y = j;
}
if(dire[id]) {
if(dir) {
while(check(x+1, y) && map[e(x+1, y)] == id) x++;
int nx = x, ny = y;
while(check(nx+1, ny) && map[e(nx+1, ny)] == 0) nx++;
while(check(x, y) && map[e(x, y)] == id) {
map[e(x, y)] = 0;
map[e(nx, ny)] = id;
x--; nx--;
}
}else {
while(check(x-1, y) && map[e(x-1, y)] == id) x--;
int nx = x, ny = y;
while(check(nx-1, ny) && map[e(nx-1, ny)] == 0) nx--;
while(check(x, y) && map[e(x, y)] == id) {
map[e(x, y)] = 0;
map[e(nx, ny)] = id;
x++; nx++;
}
}
}else {
if(dir) {
while(check(x, y+1) && map[e(x, y+1)] == id) y++;
int nx = x, ny = y;
while(check(nx, ny+1) && map[e(nx, ny+1)] == 0) ny++;
while(check(x, y) && map[e(x, y)] == id) {
map[e(x, y)] = 0;
map[e(nx, ny)] = id;
y--; ny--;
}
}else {
while(check(x, y-1) && map[e(x, y-1)] == id) y--;
int nx = x, ny = y;
while(check(nx, ny-1) && map[e(nx, ny-1)] == 0) ny--;
while(check(x, y) && map[e(x, y)] == id) {
map[e(x, y)] = 0;
map[e(nx, ny)] = id;
y++; ny++;
}
}
}
return map;
}
vector<int> bfs() {
vector<int> now, nxt;
q.push(s);
vis.insert(s);
if(isend(s)) return s;
while(!q.empty()) {
now = q.front();
q.pop();
for(int i=1; i <= n; i++) {
nxt = move(now, i, 0);
if(vis.find(nxt) == vis.end()) {
vis.insert(nxt);
path[nxt] = {now, i, 0};
if(isend(nxt)) return nxt;
q.push(nxt);
}
nxt = move(now, i, 1);
if(vis.find(nxt) == vis.end()) {
vis.insert(nxt);
path[nxt] = {now, i, 1};
if(isend(nxt)) return nxt;
q.push(nxt);
}
}
}
return s;
}
void printmap(vector<int> & map) {
for(int i=0; i < 6; i++) {
for(int j=0; j < 6; j++) {
printf("%d ", map[e(i, j)]);
}
putchar('\n');
}
}
void printres(vector<int> & now) {
if(now == s) {
printmap(now);
return ;
}
Move m = path[now];
printres(m.now);
putchar('\n');
printf("%d ", m.id);
if(dire[m.id]) {
if(m.dire) {
printf("向下移动\n");
}else {
printf("向上移动\n");
}
}else {
if(m.dire) {
printf("向右移动\n");
}else {
printf("向左移动\n");
}
}
putchar('\n');
printmap(now);
}
int main() {
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
for(int i=0; i < 6; i++) {
for(int j=0; j < 6; j++) {
int x;
scanf("%d", &x);
s.push_back(x);
}
}
scanf("%d%d", &n, &g);
int d[2][4] = {1,-1,0,0,0,0,1,-1};
for(int i=0; i < 6; i++) {
for(int j=0; j < 6; j++) {
int now = s[e(i, j)];
for(int k=0; k < 4; k++) {
int x = i + d[0][k];
int y = j + d[1][k];
if(!check(x, y)) continue;
if(s[e(x, y)] == now) {
if(k <= 1) dire[now] = 1;
else dire[now] = 0;
}
}
}
}
vector<int> myend = bfs();
// printmap(myend);
printres(myend);
return 0;
}
输入格式如下,一个 6*6
矩阵,0
代表空白区域,从 1
开始给块编号,然后下面的两个数字9 5
,前一个数字9
代表一共9
个块,后面的数字5
代表编号为5
的块是目标块,也就是上图的绿色块。
1 2 3 3 3 0
1 2 0 0 4 0
1 5 5 0 4 0
6 6 6 0 4 0
0 0 7 8 8 0
9 9 7 0 0 0
9 5
程序编译出来后,在同一目录下创建一个文本文件in.txt
和一个out.txt
文件,把输入数据写入in.txt
文件中,保存完数据后运行编译出来的执行文件,运行结果会写入在out.txt
文件,输出结果如下,按文字描述操作即可过关。
注意:要是程序运行结果只输出了初始时的数据(6*6矩阵)代表你数据输错了或无解,输入数据以空格分隔每个数。
1 2 3 3 3 0
1 2 0 0 4 0
1 5 5 0 4 0
6 6 6 0 4 0
0 0 7 8 8 0
9 9 7 0 0 0
5 向右移动
1 2 3 3 3 0
1 2 0 0 4 0
1 0 5 5 4 0
6 6 6 0 4 0
0 0 7 8 8 0
9 9 7 0 0 0
2 向下移动
1 0 3 3 3 0
1 2 0 0 4 0
1 2 5 5 4 0
6 6 6 0 4 0
0 0 7 8 8 0
9 9 7 0 0 0
3 向左移动
1 3 3 3 0 0
1 2 0 0 4 0
1 2 5 5 4 0
6 6 6 0 4 0
0 0 7 8 8 0
9 9 7 0 0 0
4 向上移动
1 3 3 3 4 0
1 2 0 0 4 0
1 2 5 5 4 0
6 6 6 0 0 0
0 0 7 8 8 0
9 9 7 0 0 0
6 向右移动
1 3 3 3 4 0
1 2 0 0 4 0
1 2 5 5 4 0
0 0 0 6 6 6
0 0 7 8 8 0
9 9 7 0 0 0
7 向上移动
1 3 3 3 4 0
1 2 0 0 4 0
1 2 5 5 4 0
0 0 7 6 6 6
0 0 7 8 8 0
9 9 0 0 0 0
9 向右移动
1 3 3 3 4 0
1 2 0 0 4 0
1 2 5 5 4 0
0 0 7 6 6 6
0 0 7 8 8 0
0 0 0 0 9 9
1 向下移动
0 3 3 3 4 0
0 2 0 0 4 0
0 2 5 5 4 0
1 0 7 6 6 6
1 0 7 8 8 0
1 0 0 0 9 9
2 向下移动
0 3 3 3 4 0
0 0 0 0 4 0
0 0 5 5 4 0
1 0 7 6 6 6
1 2 7 8 8 0
1 2 0 0 9 9
5 向左移动
0 3 3 3 4 0
0 0 0 0 4 0
5 5 0 0 4 0
1 0 7 6 6 6
1 2 7 8 8 0
1 2 0 0 9 9
7 向上移动
0 3 3 3 4 0
0 0 7 0 4 0
5 5 7 0 4 0
1 0 0 6 6 6
1 2 0 8 8 0
1 2 0 0 9 9
6 向左移动
0 3 3 3 4 0
0 0 7 0 4 0
5 5 7 0 4 0
1 6 6 6 0 0
1 2 0 8 8 0
1 2 0 0 9 9
8 向左移动
0 3 3 3 4 0
0 0 7 0 4 0
5 5 7 0 4 0
1 6 6 6 0 0
1 2 8 8 0 0
1 2 0 0 9 9
9 向左移动
0 3 3 3 4 0
0 0 7 0 4 0
5 5 7 0 4 0
1 6 6 6 0 0
1 2 8 8 0 0
1 2 9 9 0 0
4 向下移动
0 3 3 3 0 0
0 0 7 0 0 0
5 5 7 0 0 0
1 6 6 6 4 0
1 2 8 8 4 0
1 2 9 9 4 0
3 向右移动
0 0 0 3 3 3
0 0 7 0 0 0
5 5 7 0 0 0
1 6 6 6 4 0
1 2 8 8 4 0
1 2 9 9 4 0
7 向上移动
0 0 7 3 3 3
0 0 7 0 0 0
5 5 0 0 0 0
1 6 6 6 4 0
1 2 8 8 4 0
1 2 9 9 4 0
吐了,用PPT玩了50关。
标签:map,nx,ny,int,华容道,BFS,++,2022,id 来源: https://blog.csdn.net/imagine7/article/details/122763731