【最短路 && 思维】Gym - 101291C Buggy Robot

Step1 Problem:

给你 n*m 的矩阵,其中:
‘R’:机器人
‘E’:终点
‘#’:墙
‘.’:空地
给你一个指令 (由 U D L R 组成),机器人会按照这个指令移动,如果下一步有墙或者出了边界,则跳过该操作。
你可以在指令中添加字母,或者删除指令中的字母,问你最少操作,使得机器人能到达 E

Step2 Ideas:

难点想到最短路
求 R->E 的最少操作。
状态 dis[i][j][k]:第 k 个指令,到达 i,j 的最少操作。
然后三种情况:

  1. 添加一个字符走
  2. 删除一个字符
  3. 直接走

Step3 Code:

#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 55;
struct node
{
    int u, v, k, step;
    bool operator < (const node &b) const {
        return step > b.step;
    }
};
char Map[N][N];
char s[N];
int dp[N][N][N], n, m, su, sv, eu, ev, len;
int x[5] = {1, -1, 0, 0};
int y[5] = {0, 0, 1, -1};
bool ok(int u, int v)
{
    if(u >= 1 && u <= n && v >= 1 && v <= m) return 1;
    else return 0;
}
void solve()//迪杰斯特拉
{
    memset(dp, inf, sizeof(dp));
    dp[su][sv][0] = 0;
    priority_queue<node> q;
    q.push((node){su, sv, 0, 0});
    while(!q.empty())
    {
        node tmp = q.top(); q.pop();
        int u = tmp.u, v = tmp.v, k = tmp.k, step = tmp.step;
        if(Map[u][v] == 'E') continue;
       // printf("%d %d %d %d\n", u, v, k, step);
        int tu, tv;
        for(int i = 0; i < 4; i++)//第一种情况
        {
            tu = u + x[i];
            tv = v + y[i];
          //  printf("%d %d %d %d\n",tu, tv, k, dp[tu][tv][k]);
            if(ok(tu, tv) && Map[tu][tv] != '#' && dp[tu][tv][k] > step+1)
            {
                dp[tu][tv][k] = step+1;
                q.push((node){tu, tv, k, dp[tu][tv][k]});
            }
        }
        if(k+1 <= len)
        {
            if(dp[u][v][k+1] > step+1)//第二种情况
            {
                dp[u][v][k+1] = step+1;
                q.push((node){u, v, k+1, dp[u][v][k+1]});
            }
            if(s[k+1] == 'U')
            {
                tu = u-1;
                tv = v;
            }
            else if(s[k+1] == 'D')
            {
                tu = u+1;
                tv = v;
            }
            else if(s[k+1] == 'L')
            {
                tu = u;
                tv = v-1;
            }
            else if(s[k+1] == 'R')
            {
                tu = u;
                tv = v+1;
            }
            if(ok(tu, tv) && Map[tu][tv] != '#')//第三种
            {
                if(dp[tu][tv][k+1] > step)
                {
                    dp[tu][tv][k+1] = step;
                    q.push((node){tu, tv, k+1, dp[tu][tv][k+1]});
                }
            }
            else if((ok(tu, tv) && Map[tu][tv] == '#') || !ok(tu,tv))
            {
                if(dp[u][v][k+1] > step)
                {
                    dp[u][v][k+1] = step;
                    q.push((node){u, v, k+1, dp[u][v][k+1]});
                }
            }
        }
    }
}
int main()
{
    while(~scanf("%d %d", &n, &m))
    {
        for(int i = 1; i <= n; i++)
        {
            scanf("%s", Map[i]+1);
            for(int j = 1; j <= m; j++)
            {
                if(Map[i][j] == 'R') {
                    su = i, sv = j;
                }
                if(Map[i][j] == 'E') {
                    eu = i, ev = j;
                }
            }
        }
        scanf("%s", s+1);
        len = strlen(s+1);
        solve();
        int ans = inf;
        for(int i = 1; i <= len; i++)
            ans = min(ans, dp[eu][ev][i]);
        printf("%d\n", ans);
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值