4 4 SX.. XX.. .... 1..D 4 4 S.X1 .... ..XX ..XD 0 0
-1 9
6 6
S1XX3X
XXXXXX
2XXXXX
XXXXXX
XXXXXX
X1XDXX
29
5 3
S..
1X.
XX.
...
XXD
6
5 6
S.XXXX
21..XX
XXXXXX
XXXXXX
3XXXDX
11
对于这个题真的是无力吐槽,这个题目有几个难点:
1.vis数组不能再是普通的二维数组
2.不能在原来的地图上炸X.需要用结构体伴随一个map
3.使用优先队列,炸X的方式有很多,我们不得不借用优先队列的特性来完成题目.
思路很清晰,遇到炸弹就放在兜兜里,然后炸弹的地方变成‘.’,遇到‘.’就直接走上去,遇到'X'就炸一下子(要是没有就不炸)
思路很简单,代码实现却是充满了坑,各种坑。大坑。
废话不啰嗦,这里直接上代码:
#include <stdio.h> #include <string.h> #include <queue> using namespace std; struct node { int x,y,num,step; char mp[15][15];//伴随map(这里不能在原图上炸X) bool friend operator<(node a,node b) { return a.step>b.step; } } t; int dir[4][2]= {{1,0},{0,1},{-1,0},{0,-1}}; char s[15][15]; int vis[15][15][55]; int n,m,ex,ey,flag; int bfs(int x,int y) { priority_queue<node>q; int i,j; for(i=0; i<n; i++) for(j=0; j<m; j++) t.mp[i][j]=s[i][j];//图的copy t.step=0; t.num=0; t.x=x; t.y=y; vis[t.x][t.y][0]++; q.push(t); while(!q.empty()) { t=q.top(); if(t.x==ex && t.y==ey) return t.step; for(i=0; i<4; i++)//下边的思路还是比较清晰的. { t.step++; t.x+=dir[i][1]; t.y+=dir[i][0]; if(t.x>=0 && t.x<n && t.y>=0 && t.y<m && vis[t.x][t.y][t.num]<100)//最多也就重复走100次 { if(t.mp[t.x][t.y]=='.') { vis[t.x][t.y][t.num]++; q.push(t); } else if(t.mp[t.x][t.y]=='X' && t.num>0) { vis[t.x][t.y][t.num]++; t.step++; t.num--; t.mp[t.x][t.y]='.'; q.push(t); } else if(t.mp[t.x][t.y]>='1' && t.mp[t.x][t.y]<='9') { vis[t.x][t.y][t.num]++; t.num+=t.mp[t.x][t.y]-'0'; t.mp[t.x][t.y]='.'; q.push(t); } } t=q.top(); } q.pop(); } return -1; } int main() { int i,j,x1,y1; while(~scanf("%d%d",&n,&m) && n) { for(i=0; i<n; i++) scanf("%s",s[i]); for(i=0; i<n; i++) for(j=0; j<m; j++) { if(s[i][j]=='S') { s[i][j]='.'; x1=i,y1=j; } else if(s[i][j]=='D') { s[i][j]='.'; ex=i,ey=j; } } memset(vis,0,sizeof vis); printf("%d\n",bfs(x1,y1)); } }