hdu1072(dfs和bfs)
题意:有一个n*m的矩阵迷宫,2是起点,3是终点,0是墙不能走,1是路,现在有6分钟炸弹要爆炸,没走一步花一分钟,问你是否能到达终点
能,则输出最短时间,不能输出-1。而4是重置时间,将时间变为6分钟,注意的是,不能正好时间为0,到达终点或者重置时间。
bfs的思路比较简单,就是从起点开始搜索。遇到终点则就是最短时间,遇到4(重置设备)时间变为6分钟,并将此地方变为墙,因为每个重置设备在保证时间最短的情况下,只会有一次,如果返回来多次使用,只会增加消耗的时间,不会增加可花费的时间。
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<queue> using namespace std; struct node{ int x,y,step,time; }; int map[10][10],n,m; int bx,by; int dx[4]={-1,1,0,0}; int dy[4]={0,0,-1,1}; void bfs() { queue<node>q; node t={bx,by,0,6};//起点的状态 q.push(t); while(!q.empty()) { node p; p=q.front(); q.pop(); for(int i=0;i<4;i++) { t.x=dx[i]+p.x; t.y=dy[i]+p.y; t.step=p.step+1; t.time=p.time-1; if(t.x>=0&&t.x<n&&t.y>=0&&t.y<m&&t.time>0&&map[t.x][t.y]!=0)//可行走的情况 { if(map[t.x][t.y]==3)//到达终点,就是最短时间 { cout<<t.step<<endl; return ; } if(map[t.x][t.y]==4)//遇到重置设备 { t.time=6; map[t.x][t.y]=0; } q.push(t); } } } cout<<-1<<endl;//始终没有搜索到终点,不能到达 return ; } int main() { int t; cin>>t; while(t--) { cin>>n>>m; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { cin>>map[i][j]; if(map[i][j]==2) { bx=i,by=j;//起点 } } } bfs(); } return 0; }
而dfs的思路稍微复杂些,要考虑用重置设备后要返回的情况。但是我们可以知道如果要重复走走过的路,他的消耗时间一定多了,但剩下的时间一定要比原来多才有用。要不然剩下的时间少了,消耗的时间多了,谁会干着这种吃力不讨好的事?
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<queue> #define inf 0x3f3f3f3f using namespace std; int n,m,map[10][10],step[10][10],time[10][10],flag,ans; int bx,by,ex,ey; void dfs(int x,int y,int sum,int T)//sum为花费时间,T为还剩的时间 { if(T<=0||map[x][y]==0||x<0||x>=n||y<0||y>=m)//不合法和不可行的情况 return ; //cout<<x<<" "<<y<<endl; if(x==ex&&y==ey)//遇到终点 { flag=1;//标记 ans=min(ans,sum);//取最小时间 return ; } if(map[x][y]==4)//遇到重置设备 T=6; if(sum>=step[x][y]&&time[x][y]>=T)//走已经走过的路,但剩下的时间少于原来的时间就不会走 return ; step[x][y]=sum;//更新这一步的消耗时间和剩余时间 time[x][y]=T; dfs(x,y-1,sum+1,T-1);//左 dfs(x,y+1,sum+1,T-1);//右 dfs(x-1,y,sum+1,T-1);//下 dfs(x+1,y,sum+1,T-1);//上 } int main() { int t; cin>>t; while(t--) { flag=0; ans=inf; cin>>n>>m; for(int i=0;i<n;i++) for(int j=0;j<m;j++) { time[i][j]=0; step[i][j]=inf; cin>>map[i][j]; if(map[i][j]==2)//起点 { bx=i; by=j; } if(map[i][j]==3)//终点 { ex=i; ey=j; } } dfs(bx,by,0,6); if(flag==0) cout<<-1<<endl; else cout<<ans<<endl; } return 0; }