gym 101291C Buggy Robot (bfs+dp)

You are trying to program a robot to navigate through a 2-dimensional maze and find the exit. The maze can be represented as a grid with n rows and m columns. Some grid cells have obstacles that the robot cannot pass. The other cells are empty, which the robot can freely pass. Exactly one of the empty cells in the grid is marked as the exit, and the robot will exit the maze immediately once it reaches there. You can program the robot by sending it a command string . A command string consists of char-  acters ‘L’, ‘U’, ‘R’, ‘D’, corresponding to the directions left, up, right, down, respectively. The robotwill then start executing the commands, by moving to an adjacent cell in the directions specified by the command string. If the robot would run into an obstacle or off the edge of the grid, it will ignore the command, but it will continue on to remaining commands. The robot will also ignore all commands after reaching the exit cell. Your friend sent you a draft of a command string, but you quickly realize that the command string will not necessarily take the robot to the exit. You would like to fix the string so that the robot will reach the exit square. In one second, you can delete an arbitrary character, or add an arbitrary character at an arbitrary position. Find how quickly you can fix your friend’s command string. You do not care how long it takes the robot to find the exit, but only how long it takes to repair the command string.

Input

The first line of input contains the two integers n and m (1 ≤ n, m ≤ 50). Each of the next n lines contains m characters, describing the corresponding row of the grid. Empty cells are denoted as ‘ . ’, the robot’s initial position is denoted as ‘ R ’, obstacles are denoted as ‘ # ’, and the exit is denoted as ‘ E ’. The next and final line of input contains your friend’s command string, consisting of between 1 and 50 characters, inclusive. It is guaranteed that the grid contains exactly one ‘ R ’ and one ‘ E ’, and that there is always a path from ‘ R ’ to ‘ E ’.

Output

Print, on a single line, a single integer indicating the minimum amount of time to fix the program.

Sample Input

Sample Input

3 3

R..

.#.

..E

LRDD

Sample Output

1

Sample input

2 4

R.#.

#..E

RRUUDDRRUUUU

Sample Output

0

 

题目大意:

在一个图里从一个点开始到终点,给你一串指令,问如何修改能从起点到达终点(修改数最小);

题解思路:

dp[i][j][k]表示从起点开始到(i j)在第k个指令的最小修改数;

所以转移有3种

新加指令  if(dp[xx][yy][dep]>dp[x][y][dep]+1) dp[xx][yy][dep]=dp[x][y][dep]+1;

删去指令 if(dp[x][y][dep+1]>dp[x][y][dep]+1)   dp[x][y][dep+1]=dp[x][y][dep]+1;

按照指令走下一部  

if(dp[xx][yy][dep+1]>dp[x][y][dep]) dp[xx][yy][dep+1]=dp[x][y][dep];

bfs 便利每个状态

最后min dp[edx][edy][i] 为答案

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<algorithm>

#define mem(a,b) memset(a,b,sizeof(a))
#define For(i,a,b) for(int i=a,i<=n;i++)
#define ll long long
#define inf 0x3f3f3f3f

const int maxn=55;

using namespace std;

struct node{
    int x,y,dep;
};

char a[maxn][maxn],s[maxn];
int dp[maxn][maxn][maxn],n,m;
int dx[4]={0,0,-1,1},dy[4]={-1,1,0,0};
map<char, int>cmd;

int cheek(int x,int y)
{
    if(x>=1&&x<=n&&y>=1&&y<=m&&a[x][y]!='#') return 1;
    return 0;
}

int main(){
    int stx,sty,edx,edy;
    cmd['L']=0,cmd['R']=1,cmd['U']=2,cmd['D']=3;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>a[i][j];
            if(a[i][j]=='R')
            {
                stx=i;
                sty=j;
            }
            if(a[i][j]=='E')
            {
                edx=i;
                edy=j;
            }
        }
    }
//    for(int i=1;i<=n;i++)
//    {
//        for(int j=1;j<=m;j++)
//        {
//            cout<<a[i][j];
//        }
//        cout<<endl;
//    }
    queue<node>q;
    scanf("%s",s+1);
    int l=strlen(s+1);
//    for(int i=1;i<=l;i++)
//    {
//        cout<<s[i];
//    }cout<<endl;
    mem(dp,inf);
    dp[stx][sty][0]=0;
    q.push((node){stx,sty,0});
    while(!q.empty())
    {
        int x=q.front().x,y=q.front().y,dep=q.front().dep;
        q.pop();
        for(int i=0;i<4;i++)//
        {
            int xx=x+dx[i],yy=y+dy[i];
            if(cheek(xx,yy))
            if(dp[xx][yy][dep]>dp[x][y][dep]+1)//如果到周围的花费小更新(新加指令)
            {
                dp[xx][yy][dep]=dp[x][y][dep]+1;
                q.push((node){xx,yy,dep});
            }
        }
        if(dep<l)
        {
            if(dp[x][y][dep+1]>dp[x][y][dep]+1)//(删除第dep条指令)
            {
                dp[x][y][dep+1]=dp[x][y][dep]+1;
                q.push((node){x,y,dep+1});
            }

            int xx=x+dx[cmd[s[dep+1]]],yy=y+dy[cmd[s[dep+1]]];//按照指令向下走
            if(!cheek(xx,yy)) xx=x,yy=y;//如果非法 在原地
            if(dp[xx][yy][dep+1]>dp[x][y][dep])
            {
                dp[xx][yy][dep+1]=dp[x][y][dep];
                q.push((node){xx,yy,dep+1});
            }
        }
    }
    int ans=inf;
    for(int i=0;i<=l;i++)
    {
        ans=min(ans,dp[edx][edy][i]);
    }
    printf("%d\n",ans);
    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值