列表

详情


ZJ5. 编程题1

描述

有一个推箱子的游戏, 一开始的情况如下图:

上图中, '.' 表示可到达的位置, '#' 表示不可到达的位置,其中 S 表示你起始的位置, 0表示初始箱子的位置, E表示预期箱子的位置,你可以走到箱子的上下左右任意一侧, 将箱子向另一侧推动。如下图将箱子向右推动一格;

..S0.. -> ...S0.

注意不能将箱子推动到'#'上, 也不能将箱子推出边界;

现在, 给你游戏的初始样子, 你需要输出最少几步能够完成游戏, 如果不能完成, 则输出-1。

输入描述

第一行为2个数字,n, m, 表示游戏盘面大小有n 行m 列(5< n, m < 50);
后面为n行字符串,每行字符串有m字符, 表示游戏盘面;

输出描述

一个数字,表示最少几步能完成游戏,如果不能,输出-1;

示例1

输入:

3 6
.S#..E
.#.0..
......

输出:

11

原站题解

C++ 解法, 执行用时: 3ms, 内存消耗: 2168KB, 提交时间: 2020-08-17

#include <iostream>
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <string>
#include <ctime>
using namespace std;
#define maxn 55

int n, m;
char board[maxn][maxn];
struct point {
	int x;
	int y;
	point() : x(), y() {} // 无参构造函数
	point(int a, int b) : x(a), y(b) {} // 有参构造函数
};
point start, expect, original;
bool visited[maxn][maxn][maxn][maxn];
struct Node {
	int person_x, person_y, box_x, box_y, step, weight;
	bool operator < (const Node& temp) const { // 重载,优先级
		return temp.weight + abs(temp.person_x - temp.box_x) + abs(temp.person_y - temp.box_y) + temp.step
			< weight + abs(person_x - box_x) + abs(person_y - box_y) + step;
	}
};
Node tmp;
int direction[4][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };

bool judge(int x, int y) {
	if (x >= 1 && x <= n && y >= 1 && y <= m && board[x][y] != '#') {
		return true;
	}
	return false;
}

int bfs() {
	tmp = { start.x, start.y, original.x, original.y, 0, 0 };
	priority_queue<Node> queue;
	queue.push(tmp);
	visited[start.x][start.y][original.x][original.y] = 1;
	while (!queue.empty()) {
		Node cur = queue.top();
		//cout << cur.person_x << ", " << cur.person_y << endl;
		queue.pop();
		if (cur.box_x == expect.x && cur.box_y == expect.y) { // 箱子成功推到预期位置
			return cur.step;
		}
		for (int i = 0; i < 4; i++) {
			int person_x = cur.person_x + direction[i][0];
			int person_y = cur.person_y + direction[i][1];
			int box_x = cur.box_x;
			int box_y = cur.box_y;
			if (person_x == box_x && person_y == box_y) { // 碰到箱子就推箱子
				box_x += direction[i][0];
				box_y += direction[i][1];
			}
			if (!judge(person_x, person_y) || !judge(box_x, box_y)) {
				continue;
			}
			if (visited[person_x][person_y][box_x][box_y] == 1) {
				continue;
			}
			visited[person_x][person_y][box_x][box_y] = 1;
			queue.push({person_x, person_y, box_x, box_y, cur.step + 1, abs(expect.x - box_x) + abs(expect.y - box_y)});
		}
	}
	return -1;
}

int main() {
	cin >> n >> m;
	string str;
	for (int i = 1; i <= n; i++) {
		cin >> str;
		for (int j = 1; j <= m; j++) {
			board[i][j] = str[j - 1];
			if (board[i][j] == 'S') {
				start = { i, j };
			}
			else if (board[i][j] == '0') {
				original = { i, j };
			}
			else if (board[i][j] == 'E') {
				expect = { i, j };
			}
		}
	}
	cout << bfs() << endl;
	system("pause");
	return 0;
}

C++ 解法, 执行用时: 3ms, 内存消耗: 2184KB, 提交时间: 2020-08-08

#include <iostream>
#include <cmath>
#include <vector>
#include <string>
#include <unordered_set>
#include <algorithm>
#include <unordered_map>
#include <limits.h>
#include <queue>
using namespace std;
const int N = 55;
bool vis[N][N][N][N]; /// vis[a][b][c][d] 表示人在 (a,b)处,
char graph[N][N];
int n, m, px, py, boxx, boxy, ex, ey;
struct Node
{
    int px, py, boxx, boxy, step, weight;
    bool operator<(const Node &rs) const
    { /// 重载, step大的Node优先级小

        return rs.weight + abs(rs.px - rs.boxx) + abs(rs.py - rs.boxy) + rs.step < weight + abs(px - boxx) + abs(py - boxy) + step;
    }
} s;
/*
struct Node
{
    int px, py, boxx, boxy, step;
    bool operator<(const Node &rs) const
    { /// 重载, step大的Node优先级小
        return rs.step < step;
    }
} s;*/
int dir[][2] = {1, 0, -1, 0, 0, 1, 0, -1};
bool judge(int x, int y)
{
    if (x < 0 || x >= n || y < 0 || y >= m || graph[x][y] == '#')
        return false;
    return true;
}
int bfs()
{
    s = {px, py, boxx, boxy, 0, 0};
    priority_queue<Node> q;
    q.push(s);
    vis[px][py][boxx][boxy] = 1;
    while (!q.empty())
    {
        Node u = q.top();
        q.pop();
        //printf("%d %d %d %d\n",u.px,u.py,u.boxx,u.boxy);
        if (u.boxx == ex && u.boxy == ey)
            return u.step;
        for (int i = 0; i < 4; i++)
        {
            int pxx = u.px + dir[i][0];
            int pyy = u.py + dir[i][1]; /// 人往该方向走了一步
            int boxx = u.boxx, boxy = u.boxy;
            if (pxx == boxx && pyy == boxy)
            { /// 碰到了箱子则将箱子向外推动一格
                boxx += dir[i][0];
                boxy += dir[i][1];
            }
            if (!judge(pxx, pyy) || !judge(boxx, boxy))
                continue;
            if (vis[pxx][pyy][boxx][boxy])
                continue;
            vis[pxx][pyy][boxx][boxy] = 1;
            auto weight = abs(ex - boxx) + abs(ey - boxy);
            q.push({pxx, pyy, boxx, boxy, u.step + 1, weight});
        }
    }
    return -1;
}
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++)
    {
        scanf("%s", graph[i]);
        for (int j = 0; j < m; j++)
        {
            if (graph[i][j] == '0')
                boxx = i, boxy = j, graph[i][j] = '.';
            if (graph[i][j] == 'S')
                px = i, py = j, graph[i][j] = '.';
            if (graph[i][j] == 'E')
                ex = i, ey = j, graph[i][j] = '.';
        }
    }
    printf("%d\n", bfs());
    system("pause");
    return 0;
}

C++ 解法, 执行用时: 4ms, 内存消耗: 1920KB, 提交时间: 2020-08-18

#include <iostream>
#include <cmath>
#include <vector>
#include <string>
#include <unordered_set>
#include <algorithm>
#include <unordered_map>
#include <limits.h>
#include <queue>
using namespace std;
const int maxmn=55;
bool arrival [maxmn][maxmn][maxmn][maxmn];
char mymap[maxmn][maxmn];
int n=0,m=0,sx=0,sy=0,bx=0,by=0,ex=0,ey=0;
struct PosInfo{
    int sx, sy, bx,by,step, weight;
    bool operator <(const PosInfo& pi)const{
        int val1=pi.weight+
            abs(pi.sx-pi.bx)+
            abs(pi.sy-pi.by)+
            pi.step;
        int val2=weight+
            abs(sx-bx)+
            abs(sy-by)+
            step;
        return val1 < val2;
    }
};
int dir[][2]={1,0,-1,0,0,1,0,-1};
bool check(int x,int y) {
     if(x<0||y<0||x>=n||y>=m||mymap[x][y]=='#')
         return false;
     return true;
}

int bfs(){
    priority_queue<PosInfo> queue1;
    queue1.push({sx,sy,bx,by,0,0});
    arrival[sx][sy][bx][by] = true;
    while(!queue1.empty()){
        PosInfo posinfo=queue1.top();
        queue1.pop();
        if(ex==posinfo.bx&&ey==posinfo.by) return posinfo.step;
        for(int i=0;i<4;i++){
            int tsx=posinfo.sx+dir[i][0];
            int tsy=posinfo.sy+dir[i][1];
            int tbx=posinfo.bx;
            int tby=posinfo.by;
            if(tsx==tbx&&tsy==tby){
                tbx+=dir[i][0];
                tby+=dir[i][1];
            }
            if(!check(tsx,tsy)||!check(tbx,tby)) continue;
            if(arrival[tsx][tsy][tbx][tby]) continue;
            arrival[tsx][tsy][tbx][tby]=true;
            int weight=abs(ex-tbx)+abs(ey-tby);
            queue1.push({tsx,tsy,tbx,tby,posinfo.step+1,weight});
        }
    }
    return -1;
}

int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>mymap[i][j];
            if(mymap[i][j]=='S'){
                sx=i;
                sy=j;
            }
            if(mymap[i][j]=='0'){
                bx=i;
                by=j;
            }
            if(mymap[i][j]=='E'){
                ex=i;
                ey=j;
            }
        }
    }
    
   
    cout<<bfs()<<endl;
    return 0;
}

C++ 解法, 执行用时: 4ms, 内存消耗: 2168KB, 提交时间: 2020-08-10

#include <iostream>
#include <cmath>
#include <vector>
#include <string>
#include <unordered_set>
#include <algorithm>
#include <unordered_map>
#include <limits.h>
#include <queue>
using namespace std;
const int N = 55;
bool vis[N][N][N][N]; /// vis[a][b][c][d] 表示人在 (a,b)处,
char graph[N][N];
int n, m, px, py, boxx, boxy, ex, ey;
struct Node
{
    int px, py, boxx, boxy, step, weight;
    bool operator<(const Node &rs) const
    { /// 重载, step大的Node优先级小

        return rs.weight + abs(rs.px - rs.boxx) + abs(rs.py - rs.boxy) + rs.step < weight + abs(px - boxx) + abs(py - boxy) + step;
    }
} s;
/*
struct Node
{
    int px, py, boxx, boxy, step;
    bool operator<(const Node &rs) const
    { /// 重载, step大的Node优先级小
        return rs.step < step;
    }
} s;*/
int dir[][2] = {1, 0, -1, 0, 0, 1, 0, -1};
bool judge(int x, int y)
{
    if (x < 0 || x >= n || y < 0 || y >= m || graph[x][y] == '#')
        return false;
    return true;
}
int bfs()
{
    s = {px, py, boxx, boxy, 0, 0};
    priority_queue<Node> q;
    q.push(s);
    vis[px][py][boxx][boxy] = 1;
    while (!q.empty())
    {
        Node u = q.top();
        q.pop();
        //printf("%d %d %d %d\n",u.px,u.py,u.boxx,u.boxy);
        if (u.boxx == ex && u.boxy == ey)
            return u.step;
        for (int i = 0; i < 4; i++)
        {
            int pxx = u.px + dir[i][0];
            int pyy = u.py + dir[i][1]; /// 人往该方向走了一步
            int boxx = u.boxx, boxy = u.boxy;
            if (pxx == boxx && pyy == boxy)
            { /// 碰到了箱子则将箱子向外推动一格
                boxx += dir[i][0];
                boxy += dir[i][1];
            }
            if (!judge(pxx, pyy) || !judge(boxx, boxy))
                continue;
            if (vis[pxx][pyy][boxx][boxy])
                continue;
            vis[pxx][pyy][boxx][boxy] = 1;
            auto weight = abs(ex - boxx) + abs(ey - boxy);
            q.push({pxx, pyy, boxx, boxy, u.step + 1, weight});
        }
    }
    return -1;
}
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++)
    {
        scanf("%s", graph[i]);
        for (int j = 0; j < m; j++)
        {
            if (graph[i][j] == '0')
                boxx = i, boxy = j, graph[i][j] = '.';
            if (graph[i][j] == 'S')
                px = i, py = j, graph[i][j] = '.';
            if (graph[i][j] == 'E')
                ex = i, ey = j, graph[i][j] = '.';
        }
    }
    printf("%d\n", bfs());
    system("pause");
    return 0;
}

C++ 解法, 执行用时: 4ms, 内存消耗: 2172KB, 提交时间: 2020-10-26

#include <iostream>
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <string>
#include <ctime>
using namespace std;
#define maxn 55

int n, m;
char board[maxn][maxn];
struct point {
	int x;
	int y;
	point() : x(), y() {} // 无参构造函数
	point(int a, int b) : x(a), y(b) {} // 有参构造函数
};
point start, expect, original;
bool visited[maxn][maxn][maxn][maxn];
struct Node {
	int person_x, person_y, box_x, box_y, step, weight;
	bool operator < (const Node& temp) const { // 重载,优先级
		return temp.weight + abs(temp.person_x - temp.box_x) + abs(temp.person_y - temp.box_y) + temp.step
			< weight + abs(person_x - box_x) + abs(person_y - box_y) + step;
	}
};
Node tmp;
int direction[4][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };

bool judge(int x, int y) {
	if (x >= 1 && x <= n && y >= 1 && y <= m && board[x][y] != '#') {
		return true;
	}
	return false;
}

int bfs() {
	tmp = { start.x, start.y, original.x, original.y, 0, 0 };
	priority_queue<Node> queue;
	queue.push(tmp);
	visited[start.x][start.y][original.x][original.y] = 1;
	while (!queue.empty()) {
		Node cur = queue.top();
		//cout << cur.person_x << ", " << cur.person_y << endl;
		queue.pop();
		if (cur.box_x == expect.x && cur.box_y == expect.y) { // 箱子成功推到预期位置
			return cur.step;
		}
		for (int i = 0; i < 4; i++) {
			int person_x = cur.person_x + direction[i][0];
			int person_y = cur.person_y + direction[i][1];
			int box_x = cur.box_x;
			int box_y = cur.box_y;
			if (person_x == box_x && person_y == box_y) { // 碰到箱子就推箱子
				box_x += direction[i][0];
				box_y += direction[i][1];
			}
			if (!judge(person_x, person_y) || !judge(box_x, box_y)) {
				continue;
			}
			if (visited[person_x][person_y][box_x][box_y] == 1) {
				continue;
			}
			visited[person_x][person_y][box_x][box_y] = 1;
			queue.push({person_x, person_y, box_x, box_y, cur.step + 1, abs(expect.x - box_x) + abs(expect.y - box_y)});
		}
	}
	return -1;
}

int main() {
	cin >> n >> m;
	string str;
	for (int i = 1; i <= n; i++) {
		cin >> str;
		for (int j = 1; j <= m; j++) {
			board[i][j] = str[j - 1];
			if (board[i][j] == 'S') {
				start = { i, j };
			}
			else if (board[i][j] == '0') {
				original = { i, j };
			}
			else if (board[i][j] == 'E') {
				expect = { i, j };
			}
		}
	}
	cout << bfs() << endl;
	system("pause");
	return 0;
}

上一题