这道题目是标签是动态规划,但我感觉就是宽搜
我写了2个版本
一个是求总共最小移动数目的(深搜+记忆化)
另外一个是求箱子在移动次数最小的情况下,人移动次数最少的情况(也就是题目的解答,宽搜即可)
#include<stdio.h>
#include<iostream>
#include<memory.h>
#include<string.h>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
int mp[25][25];
int dp[25][25][25][25];
int vis[25][25][25][25];
string mem[25][25][25][25];
int used[25][25];
int row, col;
int sr, sc;
int br, bc;
int tr, tc;
int coun = 0;
string manroute;
vector<string> ans;
struct node {
int r, c;
string route;
};
struct boxState {
int r;
int c;
int mr;
int mc;
string route;
};
struct state {
int r;
int c;
int mr;
int mc;
string route;
bool operator == (const state &s1)const {
if (s1.r == r && s1.c == c && s1.mr == mr && s1.mc == mc) {
return true;
}
return false;
}
};
bool bfs(int curr, int curc, int tor, int toc) {
memset(used, 0, sizeof(used));
manroute = "";
used[curr][curc] = 1;
queue<node> q;
node n;
n.r = curr;
n.c = curc;
n.route = "";
q.push(n);
int r, c, i, x, y;
while (!q.empty()) {
node nd = q.front();
q.pop();
r = nd.r;
c = nd.c;
if (r == tor && c == toc) {
manroute = nd.route;
return 1;
}
if (mp[r][c - 1] == 1 && !used[r][c - 1]) {
node t;
t.r = r;
t.c = c - 1;
t.route = nd.route + "w";
q.push(t);
used[r][c - 1] = 1;
}
if (mp[r][c + 1] == 1 && !used[r][c + 1]) {
node t;
t.r = r;
t.c = c + 1;
t.route = nd.route + "e";
q.push(t);
used[r][c + 1] = 1;
}
if (mp[r + 1][c] == 1 && !used[r + 1][c]) {
node t;
t.r = r + 1;
t.c = c;
t.route = nd.route + 's';
q.push(t);
used[r + 1][c] = 1;
}
if (mp[r - 1][c] == 1 && !used[r - 1][c]) {
node t;
t.r = r - 1;
t.c = c;
t.route = nd.route + "n";
q.push(t);
used[r - 1][c] = 1;
}
}
return 0;
}
int boxBfs() {
boxState bs;
bs.r = br;
bs.c = bc;
bs.route = "";
bs.mc = sc;
bs.mr = sr;
queue<boxState> q;
q.push(bs);
int r, c, mr, mc, i;
while (!q.empty()) {
int sz = q.size();
for (i = 0; i < sz; i++) {
boxState b = q.front();
q.pop();
r = b.r;
c = b.c;
mr = b.mr;
mc = b.mc;
if (r == tr && c == tc) {
ans.push_back(b.route);
continue;
}
mp[r][c] = 0;
if (mp[r][c - 1] == 1 && mp[r][c + 1] == 1) {
//箱子右移
if (!vis[r][c][r][c - 1]) {
if (bfs(mr, mc, r, c - 1)) {
vis[r][c][r][c - 1] = 1;
boxState t = {r, c + 1, r, c, b.route + manroute + 'E'};
q.push(t);
}
}
//箱子左移
if (!vis[r][c][r][c + 1]) {
if (bfs(mr, mc, r, c + 1)) {
vis[r][c][r][c + 1] = 1;
boxState t = {r, c - 1, r, c, b.route + manroute + 'W'};
q.push(t);
}
}
}
if (mp[r + 1][c] == 1 && mp[r - 1][c] == 1) {
//箱子上移
if (!vis[r][c][r + 1][c]) {
if (bfs(mr, mc, r + 1, c)) {
vis[r][c][r + 1][c] = 1;
boxState t = {r - 1, c, r, c, b.route + manroute + 'N'};
q.push(t);
}
}
//箱子下移
if (!vis[r][c][r - 1][c]) {
if (bfs(mr, mc, r - 1, c)) {
vis[r][c][r - 1][c] = 1;
boxState t = {r + 1, c, r, c, b.route + manroute + 'S'};
q.push(t);
}
}
}
mp[r][c] = 1;
}
if (ans.size() != 0) {
return 1;
}
}
return 0;
}
//bool dfs(int r, int c, int mr, int mc) {
//
// if (r == tr && c == tc) {
// return true;
// }
//
// if (dp[r][c][mr][mc] != -1) {
// return dp[r][c][mr][mc];
// }
//
// vector<string> v;
// string man;
// if (mp[r][c - 1] == 1 && mp[r][c + 1] == 1) {
// //箱子右移
// if (!vis[r][c][r][c - 1]) {
// vis[r][c][r][c - 1] = 1;
// mp[r][c] = 0;
// if (bfs(mr, mc, r, c - 1)) {
// mp[r][c] = 1;
// man = manroute;
// if (dfs(r, c + 1, r, c)) {
// v.push_back(man + "E" + mem[r][c + 1][r][c]);
// }
// }
// mp[r][c] = 1;
// vis[r][c][r][c - 1] = 0;
// }
//
// //箱子左移
// if (!vis[r][c][r][c + 1]) {
// vis[r][c][r][c + 1] = 1;
// mp[r][c] = 0;
// if (bfs(mr, mc, r, c + 1)) {
// mp[r][c] = 1;
// man = manroute;
// if (dfs(r, c - 1, r, c)) {
// v.push_back( man + "W" + mem[r][c - 1][r][c]);
// }
// }
// mp[r][c] = 1;
// vis[r][c][r][c + 1] = 0;
// }
// }
//
// if (mp[r + 1][c] == 1 && mp[r - 1][c] == 1) {
// //箱子上移
// if (!vis[r][c][r + 1][c]) {
// vis[r][c][r + 1][c] = 1;
// mp[r][c] = 0;
// if (bfs(mr, mc, r + 1, c)) {
// mp[r][c] = 1;
// man = manroute;
// if (dfs(r - 1, c, r, c)) {
// v.push_back(man + 'N' + mem[r - 1][c][r][c]);
// }
// }
// mp[r][c] = 1;
// vis[r][c][r + 1][c] = 0;
// }
//
// //箱子下移
// if (!vis[r][c][r - 1][c]) {
// vis[r][c][r - 1][c] = 1;
// mp[r][c] = 0;
// if (bfs(mr, mc, r - 1, c)) {
// mp[r][c] = 1;
// man = manroute;
// if (dfs(r + 1, c, r, c)) {
// v.push_back(man + 'S' + mem[r + 1][c][r][c]);
// }
// }
// mp[r][c] = 1;
// vis[r][c][r - 1][c] = 0;
// }
// }
//
// if (v.size() == 0) {
// return dp[r][c][mr][mc] = 0;
// } else {
// int index = 0;
// int minlen = v[0].length();
// for (int i = 1; i < v.size(); i++) {
// if (minlen > v[i].length()) {
// index = i;
// minlen = v[i].length();
// }
// }
// mem[r][c][mr][mc] = v[index];
// return dp[r][c][mr][mc] = 1;
// }
//
//}
void inti() {
memset(mp, -1, sizeof(mp));
memset(vis, 0, sizeof(vis));
memset(dp, -1, sizeof(dp));
ans.clear();
// int i, j, k, c;
// for (i = 0; i < row + 1; i++) {
// for (j = 0; j < col + 1; j++) {
// for (k = 0; k < row + 1; k++) {
// for (c = 0; c < col + 1; c++) {
// mem[i][j][k][c] = "";
// }
// }
// }
// }
}
int main() {
string str;
while (scanf("%d%d", &row, &col)) {
if (!row && !col) break;
inti();
//input
for (int i = 1; i <= row; i++) {
cin >> str;
for (int j = 0; j < str.length(); j++) {
if (str[j] == '#') {
mp[i][j + 1] = 0;
} else if (str[j] == '.') {
mp[i][j + 1] = 1;
} else if (str[j] == 'S') {
mp[i][j + 1] = 1;
sr = i;
sc = j + 1;
} else if (str[j] == 'B') {
mp[i][j + 1] = 1;
br = i;
bc = j + 1;
} else if (str[j] == 'T') {
mp[i][j + 1] = 1;
tr = i;
tc = j + 1;
}
}
}
// if (!dfs(br, bc, sr, sc)) {
// printf("Maze #%d\n", ++coun);
// printf("Impossible.\n\n");
// } else {
// printf("Maze #%d\n", ++coun);
// cout << mem[br][bc][sr][sc] << endl << endl;
// }
if (!boxBfs()) {
printf("Maze #%d\n", ++coun);
printf("Impossible.\n\n");
} else {
printf("Maze #%d\n", ++coun);
int idx = 0;
int len = ans[0].length();
for (int i = 1; i < ans.size(); i++) {
if (len > ans[i].length()) {
len = ans[i].length();
idx = i;
}
}
cout << ans[idx] << endl << endl;
}
}
}