0
点赞
收藏
分享

微信扫一扫

zoj 1249 Pushing Boxes

程序员知识圈 2022-04-27 阅读 64

这道题目是标签是动态规划,但我感觉就是宽搜

我写了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;
		}

	}

}
举报

相关推荐

0 条评论