题目链接:https://nanti.jisuanke.com/t/40891
题意:
给你一个地图,机器人从起点到终点按照字符串的指示前进,如果遇到障碍或者出边界就停留在原地,不算违规。
问你最少修改字符串的几个字符,才能让机器人到终点。
分析:
用dp[i][j][k]表示扫描完前k个字符之后,到达地图坐标(i,j)上的最小代价。
把每个状态都依次穷举,加入队列后bfs。
#include<bits/stdc++.h> using namespace std; const int inf=0x3f3f3f3f; #define mem0(a) memset(a,0,sizeof(a)) #define meminf(a) memset(a,0x3f,sizeof(a)) const int maxn=1e5+10; char s[60][60],pre[60]; int dp[60][60][60]; int h,w; struct node{ int x,y,pos; node(int x,int y,int pos):x(x),y(y),pos(pos){} }; queue<node> q; bool check(int x,int y){ return x>0&&x<=h&&y>0&&y<=w&&s[x][y]!='#'; } int main(){ scanf("%d%d",&h,&w); int sx,sy,gx,gy; for(int i=1;i<=h;i++){ scanf("%s",s[i]+1); for(int j=1;j<=w;j++){ if(s[i][j]=='S') sx=i,sy=j; if(s[i][j]=='G') gx=i,gy=j; } } scanf("%s",pre+1); int len=strlen(pre+1); int nxt[4][2]={{0,1},{0,-1},{-1,0},{1,0}}; int m['Z'+1]; m['R']=0;m['L']=1;m['U']=2;m['D']=3; meminf(dp); dp[sx][sy][0]=0; q.push(node(sx,sy,0)); while(!q.empty()){ node now=q.front();q.pop(); for(int i=0;i<4;i++){ //在pos位置处添加一个指令 int nowx=now.x+nxt[i][0],nowy=now.y+nxt[i][1]; if(check(nowx,nowy)) if(dp[nowx][nowy][now.pos]>dp[now.x][now.y][now.pos]+1){ dp[nowx][nowy][now.pos]=dp[now.x][now.y][now.pos]+1; q.push(node(nowx,nowy,now.pos)); } } if(now.pos<len){ //在pos位置处删除一个指令 if(dp[now.x][now.y][now.pos+1]>dp[now.x][now.y][now.pos]+1){ dp[now.x][now.y][now.pos+1]=dp[now.x][now.y][now.pos]+1; q.push(node(now.x,now.y,now.pos+1)); } //按照初始指令来行进 int pos=now.pos+1;//扫描下一个 int nowx=now.x+nxt[m[pre[pos]]][0],nowy=now.y+nxt[m[pre[pos]]][1]; // cout<<" "<<nowx<<" "<<nowy<<endl; if(!check(nowx,nowy)) nowx=now.x,nowy=now.y; if(dp[nowx][nowy][now.pos+1]>dp[now.x][now.y][now.pos]){ //前者可以由后者自然转换来,如果后者代价更低是可以直接变更的 dp[nowx][nowy][now.pos+1]=dp[now.x][now.y][now.pos]; q.push(node(nowx,nowy,now.pos+1)); } } } int ans=inf; for(int i=0;i<=len;i++) ans=min(ans,dp[gx][gy][i]); cout<<ans<<endl; return 0; }