Step1 Problem:
给你 n*m 的矩阵,其中:
‘R’:机器人
‘E’:终点
‘#’:墙
‘.’:空地
给你一个指令 (由 U D L R 组成),机器人会按照这个指令移动,如果下一步有墙或者出了边界,则跳过该操作。
你可以在指令中添加字母,或者删除指令中的字母,问你最少操作,使得机器人能到达 E
Step2 Ideas:
难点想到最短路
求 R->E 的最少操作。
状态 dis[i][j][k]:第 k 个指令,到达 i,j 的最少操作。
然后三种情况:
- 添加一个字符走
- 删除一个字符
- 直接走
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;
}