首页 > 试题广场 >

编程题1

[编程题]编程题1
  • 热度指数:250 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
有一个推箱子的游戏, 一开始的情况如下图:

上图中, '.' 表示可到达的位置, '#' 表示不可到达的位置,其中 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
#include <bits/stdc++.h>
using namespace std;
int n,m;
int dir[4][2]={1,0,0,1,-1,0,0,-1};
int vis[50][50][50][50];
vector<string> view;
struct node{
        int a_x,a_y,b_x,b_y,step;
        node(int a_x,int a_y,int b_x,int b_y,int step):
                a_x(a_x),a_y(a_y),b_x(b_x),b_y(b_y),step(step){};

};
bool isTrue(int x,int y)
{
        if(x<0||y<0||x>=n||y>=m||view[x][y]=='#')
                return false;
        return true;
}
int bfs(int start_x,int start_y,int box_x,int box_y)
{
        queue<node> ans;
        ans.push(node(start_x,start_y,box_x,box_y,0));
        vis[start_x][start_y][box_x][box_y]=1;
        while(!ans.empty())
        {
                node p=ans.front();
                ans.pop();
                int ax=p.a_x;
                int ay=p.a_y;
                int bx=p.b_x;
                int by=p.b_y;
                int step=p.step;
                for(int i=0;i<4;i++)
                {
                        int new_ax=ax+dir[i][0];
                        int new_ay=ay+dir[i][1];
                        int new_bx=bx+dir[i][0];
                        int new_by=by+dir[i][1];
                        if(!isTrue(new_ax,new_ay))
                                continue;
                        //移动到箱子前
                        if((new_ax!=bx||new_ay!=by)&&vis[new_ax][new_ay][bx][by]==0)
                        {
                                vis[new_ax][new_ay][bx][by]=1;
                                ans.push(node(new_ax,new_ay,bx,by,step+1));
                        }
                        //人和箱子一起移动
                        else if(new_ax==bx&&new_ay==by&&isTrue(new_bx,new_by)&&vis[new_ax][new_ay][new_bx][new_by]==0)
                        {
                                vis[new_ax][new_ay][new_bx][new_by]==1;
                                if(view[new_bx][new_by]=='E')
                                        return step+1;
                                ans.push(node(new_ax,new_ay,new_bx,new_by,step+1));
                        }

                }
        }
        return -1;

}
int main() {
        memset(vis,-0,sizeof(vis));
        cin>>n>>m;
        view=vector<string> (n,string(""));
        for(int i=0;i<n;i++)
                cin>>view[i];
        int start_x,start_y,box_x,box_y;
        for(int i=0;i<n;i++)
                for(int j=0;j<m;j++)
                {
                        if(view[i][j]=='S')
                                start_x=i,start_y=j;
                        else if(view[i][j]=='0')
                                box_x=i,box_y=j;
                }
        cout<<bfs(start_x,start_y,box_x,box_y)<<endl;
    return 0;
}


发表于 2019-08-21 20:32:18 回复(0)
#include<iostream>
#include<queue>

using namespace std;

int m,n;
int sx,sy;
int bx,by;
char a[52][52];
int dp[52][52][52][52];
int mov[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};

int main(){
    cin>>n>>m;
    for(int i=0;i<52;i++){
        for(int j=0;j<52;j++){
            a[i][j]='#';
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
            if(a[i][j]=='S'){
                sx=i;
                sy=j;
            }
            if(a[i][j]=='0'){
                bx=i;
                by=j;
            }
        }
    }
    queue<vector<int>> q;
    vector<int> tmp={sx,sy,bx,by};
    q.push(tmp);
    int x,y,xb,yb,xn,yn;
    while(!q.empty()){
        vector<int> tmp = q.front();
        x=tmp[0],y=tmp[1],xb=tmp[2],yb=tmp[3];
        q.pop();
        for(int i=0;i<4;i++){
            xn=x+mov[i][0];
            yn=y+mov[i][1];
            if(xn!=xb || yn!=yb){
                if(a[xn][yn]!='#'&&dp[xn][yn][xb][yb]==0){
                    dp[xn][yn][xb][yb] = dp[x][y][xb][yb]+1;
                    vector<int> tmp2={xn,yn,xb,yb};
                    q.push(tmp2);
                }
            }
            else{
                int xbn=xb+mov[i][0];
                int ybn=yb+mov[i][1];
                if(a[xbn][ybn]!='#'&&dp[xn][yn][xbn][ybn]==0){
                    dp[xn][yn][xbn][ybn] = dp[x][y][xb][yb]+1;
                    if(a[xbn][ybn]=='E'){
                        cout<<dp[xn][yn][xbn][ybn]<<endl;
                        return 0;
                    }
                    vector<int> tmp2={xn,yn,xbn,ybn};
                    q.push(tmp2);
                }
            }
        }
    }
    cout<<-1<<endl;
    return 0;
}

发表于 2022-03-12 10:04:36 回复(0)
是不是测试用例有问题?27 39的矩阵,我自己加了下标

 012345678901234567890123456789012345678
0.................................#.##..
1...#............#.#....................
2........#..............................
3...............#...#...................
4....#.....#..#.........................
5.....................##....#...........
6.....#..................#...##.#.......
7.#.#.....#.......#.....................
8................###....#.......#...#...
9...............#.#..3401.#......#......
0...#.7890123456789012##2.....#.........
1....#67890123.#..#.....34567890123.....
2....#567890#.....#...............4.....
3....5456789...........#..........5.....
4.#.5434567#.........#...#........6...#.
5.#54#2#6567#....#...#.........#..7.....
6.#43212#456.........#......#...#.8#....
7..5#1S123456...##.#.........#....E.....
8.543212345.............#..#....#.....#.
9..5432#45......................#.......
0..#54345.............#...........#.....
1....545.............#.........#......#.
2.....5.....##..........................
3..#.....#..............#...............
4.............#............##.#.........
5.......#....#.#....#.........#.......#.
6#.....................#................
我手算的是45(25+19+1),如图所示。但答案是53。下划线的部分分别是S,0,E
PS:粘贴到txt文本里格式就对齐了,望大佬核对,指正【抱拳抱拳】
发表于 2019-08-23 17:08:05 回复(0)
n,m=[int(i) for i in input().split()]
map1=[]
for i in range(n):
    map1+=[i for i in input().split()]

point=[[] for i in range(3)]
state_box=[[float('inf')]*m for i in range(n)]
state_worker=[[float('inf')]*m for i in range(n)]
res=0
for i in range(n):
    for j in range(m):
        if map1[i][j]=='E':
            point[0]=[i,j]
        elif map1[i][j]=='0':
            point[1] = [i, j]
        elif map1[i][j]=='S':
            point[2]=[i,j]
def DFS(i,j,deep,object,state_matrix):
    if i<0 or j<0 or i>=n or j>=m:
        return 0
    if map1[i][j]=='#':
        return 0
    if state_matrix[i][j]<=deep:
        return 1
    state_matrix[i][j] = deep
    a1=DFS(i-1,j,deep+1,object,state_matrix)
    a2=DFS(i+1,j,deep+1,object,state_matrix)
    a3=DFS(i,j-1,deep+1,object,state_matrix)
    a4=DFS(i,j+1,deep+1,object,state_matrix)
    if object=='box':
        if (a1*a2)+(a3*a4)==0:    #排除箱子被推到角落去的情况
            state_matrix[i][j] = float('inf')
    return 1
DFS(point[0][0],point[0][1],0,'box',state_box)#create box state map
if state_box[point[1][0]][point[1][1]]==float('inf'):
    print(-1)
else:
    res+=state_box[point[1][0]][point[1][1]]
DFS(point[1][0],point[1][1],0,'worker',state_worker)
if state_worker[point[2][0]][point[2][1]]==float('inf'):
    print(-1)
res+=state_worker[point[2][0]][point[2][1]]-1
res+=2
print(res)
ac 30%
暴力法=- =
大神快出题解呀
发表于 2019-08-10 18:16:07 回复(0)