#10029. 「一本通 1.4 练习 1」棋盘游戏
![请添加图片描述](https://i-blog.csdnimg.cn/blog_migrate/636830c7700f5e411a4a18fbaaa73bbb.png)
大致思路:( 其实和魔板思路差不多)
- 这是一道很明显的bfs题,可以反过来广搜判断,基本状态什么时候可以到输入的目标状态。
- 去掉重复的,因为重复的我们之前就在更早的时候到达过了,一定不会优于之前,且会导致无限循环。
- 将输入转化为字符串,用map存储每个字符串,将其作为下标,其中的值存储经过了哪些操作
- 对于操作,我们可以定义函数来实现他们,不过多解释。
map<string, int> m;
queue <string> q;
map <string, bool> flag;
string ch(string x, int y, int p) {
if (p == 1 && y - 4 >= 0) {
swap(x[y], x[y - 4]);
return x;
}
if (p == 2 && y - 1 >= 0&&y!=4&&y!=8&&y!=12) {
swap(x[y], x[y - 1]);
return x;
}
if (p == 3&&y+1>=0&&y+4<16&&y!=3&&y!=7&&y!=11) {
swap(x[y], x[y + 1]);
return x;
}
if (p == 4 && y + 4 >= 0 && y + 4 < 16) {
swap(x[y], x[y + 4]);
return x;
}
return "0000000000000000";
}
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= 4; j++) {
cin >> a;
aa += a;
}
getchar();
}
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= 4; j++) {
cin >> a;
ansa += a;
}
getchar();
}
剩下的就是bfs模板
while (!q.empty()) {
string k, kk;
kk = q.front();
q.pop();
if(m.count(ansa)!=0){
cout<<m[ansa]+1;
exit(0);
}
for (int i = 0; i < 16; i++) {
for (int j = 1; j <= 4; j++) {
k = ch(kk, i, j);
if (m.count(k)==0 && k != "0000000000000000" && flag[k] == 0) {
m[k]=m[kk]+1;
flag[k] = 1;
if(m.count(ansa)!=0){
cout<<m[ansa];
exit(0);
}
q.push(k);
}
}
}
}
AC CODE
#include <bits/stdc++.h>
using namespace std;
char a;
string aa = "", ansa = "";
map<string, int> m;
queue <string> q;
map <string, bool> flag;
string ch(string x, int y, int p) {
if (p == 1 && y - 4 >= 0) {
swap(x[y], x[y - 4]);
return x;
}
if (p == 2 && y - 1 >= 0&&y!=4&&y!=8&&y!=12) {
swap(x[y], x[y - 1]);
return x;
}
if (p == 3&&y+1>=0&&y+4<16&&y!=3&&y!=7&&y!=11) {
swap(x[y], x[y + 1]);
return x;
}
if (p == 4 && y + 4 >= 0 && y + 4 < 16) {
swap(x[y], x[y + 4]);
return x;
}
return "0000000000000000";
}
int main() {
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= 4; j++) {
cin >> a;
aa += a;
}
getchar();
}
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= 4; j++) {
cin >> a;
ansa += a;
}
getchar();
}
if(aa==ansa){
cout<<0<<endl;
exit(0);
}
q.push(aa);
flag[aa] = 1;
m[aa] = 0;
m["0000000000000000"] = 999;
while (!q.empty()) {
string k, kk;
kk = q.front();
q.pop();
if(m.count(ansa)!=0){
cout<<m[ansa]+1;
exit(0);
}
for (int i = 0; i < 16; i++) {
for (int j = 1; j <= 4; j++) {
k = ch(kk, i, j);
if (m.count(k)==0 && k != "0000000000000000" && flag[k] == 0) {
m[k]=m[kk]+1;
flag[k] = 1;
if(m.count(ansa)!=0){
cout<<m[ansa];
exit(0);
}
q.push(k);
}
}
}
}
return 0;
}