-
题意:
题目很复杂,直接抽象化解释了。给你一个w * h的矩形格子,其中有包含一个数字“2”和一个数字“3”,剩下的格子由“0”和“1”组成,目的是计算从“2”走到“3”的最短步数,“1”代表障碍物,“0”代表可以通行。“2”可以往周围四个方向走,如果往某一个方向走,那么停下来的条件是,当这个方向上存在障碍物“1”,且会停在这个障碍物的前一个格子,并会击碎这个障碍物;如果选择的方向上没有障碍物“1”也没有终点“3”,那么就会一直运动下去,直到出界。如果遇到“3”,那么就算一种到达终点的方法。每选择往一个方向运动,就算一步。如果不能到达或者到达的步数大于10,那么就算失败,输出-1.
拿题目给的图再说明下吧~
图a:球可以往上和右运动,往上运动直到遇到障碍物才会停下,如果没有障碍物就会出界;往右运动,走一个格子后就会遇到障碍物,此时球停在第二行第三列,且第二行第四列的障碍物被击碎,变为空白格,即“0”。不能往下运动,因为与球相邻的就存在障碍物“1”,球至少运动一个格子才会击碎阻碍它的障碍物。
图b:球如果往右运动的话,会停在第二行第二列的位置,且第二行第三列的障碍物会被击碎变为空白格。
图c:球可以往上,左,右运动,往上和左会出界,往右会停在第二行第三列的位置,且第二行第四列的障碍物会被击碎。
思路:
求最短步数首先想到的是BFS,无奈BFS无法回溯,即无法恢复之前的状态,所以实现起来过于复杂。然后只好利用DFS了,但是DFS要搜索整个解答树才能找到最优解,好在题目给的限制条件是深度不能大于10,也就是O(410),1e6的时间复杂度,可以满足题意了。剩下的就是模拟了,注意判断题条件就好,具体看代码吧~
-
#include <iostream> #include<stdio.h> #include<queue> #include<string.h> using namespace std; const int maxn=101; int mp[maxn][maxn]; int dir[4][2]= {1,0,0,1,-1,0,0,-1}; int n,m; int step; int minstep; void dfs(int step,int x,int y) { if(step>10)return; for(int i=0; i<4; i++) { int tx=x+dir[i][0]; int ty=y+dir[i][1]; if(mp[tx][ty]!=1) { while(tx>=0&&tx<n&&ty>=0&&ty<m) { if(mp[tx][ty]==3) { if(step<minstep) minstep=step; return; } else if(mp[tx][ty]==1) { mp[tx][ty]=0; dfs(step+1,tx-dir[i][0],ty-dir[i][1]); mp[tx][ty]=1; break; } tx=tx+dir[i][0]; ty=ty+dir[i][1]; } } } } int main() { while(scanf("%d%d",&m,&n),n+m) { int x,y; step=0; minstep=101; for(int i=0; i<n; i++) for(int j=0; j<m; j++) { scanf("%d",&mp[i][j]); if(mp[i][j]==2) { x=i; y=j; } } dfs(1,x,y); if(minstep>10) printf("-1\n"); else printf("%d\n",minstep); } return 0; }
Curling 2.0 POJ - 3009
最新推荐文章于 2021-12-13 19:57:28 发布