棋盘游戏
Posted liuzz-20180701
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了棋盘游戏相关的知识,希望对你有一定的参考价值。
题目描述
思路
bfs主要问题就是走重复路的问题,需要设置一个vis数组防止走重复路,怎么把一个二维数组表示成一个数,扩展来说就是怎么把状态表示成一个数,看了别人的代码,可以二进制的数来记录状态,4x4的数组状态不会超过2^(17)。
然后就是怎么走的问题,规定只能向下,下右走,而向上,向左就是向下,向右的逆运算。if筛选能够向下,向右走的点就可以了。
代码
#include <cstdio>
#include <cstring>
#include <queue>
char st[5][5], ed[5][5];
int js[5][5], num_ed, tmp, cur, v, vis[135000];
std::queue<int> q;
void init() {
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
js[i][j] = 1 << (i * 4 + j);
}
}
}
int get(char arr[][5]) {
int res = 0;
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
res += js[i][j] * (arr[i][j] - '0');
}
}
return res;
}
void trans(int x, char arr[][5]) {
for (int i = 3; i >= 0; --i) {
for (int j = 3; j >= 0; --j) {
arr[i][j] = x / js[i][j] + '0';
x %= js[i][j];
}
}
}
void swap(char &x, char &y) {
char t = x;
x = y;
y = t;
}
int main() {
for (int i = 0; i < 4; ++i) scanf("%s", st[i]);
for (int i = 0; i < 4; ++i) scanf("%s", ed[i]);
init();
num_ed = get(ed);
tmp = get(st);
q.push(tmp);
memset(vis, 0x3f, sizeof(vis));
vis[tmp] = 0;
while (!q.empty()) {
cur = q.front();
v = vis[cur];
q.pop();
if (cur == num_ed) break;
trans(cur, st);
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
if (i < 3) {
swap(st[i][j], st[i + 1][j]);
tmp = get(st);
if (vis[tmp] > v + 1) {
q.push(tmp);
vis[tmp] = v + 1;
}
swap(st[i + 1][j], st[i][j]);
}
if (j < 3) {
swap(st[i][j], st[i][j + 1]);
tmp = get(st);
if (vis[tmp] > v + 1) {
q.push(tmp);
vis[tmp] = v + 1;
}
swap(st[i][j], st[i][j + 1]);
}
}
}
}
printf("%d", vis[num_ed]);
return 0;
}
以上是关于棋盘游戏的主要内容,如果未能解决你的问题,请参考以下文章