题目大意就是求在特定规则下的最短路,这个规则包含了消除障碍的操作。用BFS感觉选择消除障碍的时候不同路径会有影响,用DFS比较方便状态的还原(虽然效率比较低),因此这道题目采用DFS来写。
写的第一次提交代码是TLE,原因是忘记总步数>10就应该剪枝的条件。AC代码如下:
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = ;
struct Point{
int r, c;
Point(int r=-, int c=-):r(r),c(c){}
};
Point s,t;
int W,H;
int G[maxn][maxn];
const int dr[] = {,-,,};
const int dc[] = {,,-,};
int ans = ;
void dfs(int r,int c,int k){
if(k >= ) return ;
for(int i = ; i < ; i++){
int nr = r;
int nc = c;
int is_walk = ;
while(G[nr+dr[i]][nc+dc[i]]==){
is_walk=;
nr+=dr[i];
nc+=dc[i];
if(nr == t.r && nc == t.c){
ans = min(ans,k+);
return ;
}
}
if(!is_walk)continue;
if(G[nr+dr[i]][nc+dc[i]] == )continue ;
if(G[nr+dr[i]][nc+dc[i]] == ){
G[nr+dr[i]][nc+dc[i]] = ;
dfs(nr,nc,k+);
G[nr+dr[i]][nc+dc[i]] = ;
}
}
}
int main(){
while(scanf("%d%d ", &W, &H) && (W || H)){
ans = ;
for(int i = ; i <= H; i++){
for(int j = ; j <= W; j++)
scanf("%d",&G[i][j]);
}
for(int i = ; i <= W+; i++)
G[][i] = ,G[H+][i] = ;
for(int i = ; i <= H+; i++)
G[i][] = ,G[i][W+] = ;
for(int i = ; i <= H; i++){
for(int j = ; j <= W; j++){
if(G[i][j] == ){
s = Point(i,j);
G[i][j] = ;
}
else if (G[i][j] == ){
t = Point(i,j);
G[i][j] = ;
}
}
}
dfs(s.r,s.c,);
if(ans != && ans <= )printf("%d\n",ans);
else printf("%d\n",-);
}
return ;
}