本题是一个简单的BFS题.
大致题意是给出表格的行m,列n还有k,还有一张表格,表格中0表示路径,1表示障碍,问题是输出从表格的左上角走到右下角最短路径的步数.
其中k指的是一次可连续穿越障碍的个数,而且这个连续指的是可变换方向的连续,而不是单独一个方向上的可穿越个数,就因为这个题意没有理解清楚,简单的写了一个二维的BFS,错了.
但知道了题意之后就很好写了,只不过从二维的基础上多了一个目前已经连续穿越障碍的个数,当这个数大于K的时候就不需要扩展节点了,而且这个多出来的一维也只有在这个点是障碍的时候才有用.
代码如下:
#include <cstdio>
#include <queue>
#include <string.h>
using namespace std;
int cx,cy,cc,web[22][22],vis[22][22][22];
const int dx[4] = {0,0,-1,1};
const int dy[4] = {-1,1,0,0};
struct POINT {
int x,y,k,cnt;
POINT(int a,int b,int c, int d):x(a),y(b),k(c),cnt(d){};
};
int dfs(){
queue<POINT> p;
p.push(POINT(0,0,0,0));
vis[0][0][0] = 0;
while (!p.empty()){
POINT d = p.front(); p.pop();
if (d.x == cx -1 && d.y == cy -1) return d.k;
for (int i = 0 ;i < 4; ++ i){
int qx = d.x + dx[i], qy = d.y + dy[i],qk = d.k + 1,qcnt = d.cnt;
if (qx >= 0 && qy >= 0 && qx < cx && qy < cy ){
if (web[qx][qy] == 1) qcnt++;
if (vis[qx][qy][qcnt] != -1) continue;
if (web[qx][qy] == 1){
if (qcnt > cc) continue;
else {
vis[qx][qy][qcnt] = qk;
p.push(POINT(qx,qy,qk,qcnt));
}
}
else {
qcnt = 0;
vis[qx][qy][qcnt] = qk;
p.push(POINT(qx,qy,qk,qcnt));
}
}
}
}
return -1;
}
int main(){
int T;
scanf("%d",&T);
while (T--){
scanf("%d %d %d",&cx,&cy,&cc);
for (int i = 0;i < cx ; ++ i)
for (int j = 0;j < cy ; ++ j)
scanf("%d",&web[i][j]);
memset(vis,-1,sizeof(vis));
printf("%d\n",dfs());
}
return 0;
}