题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1072
思路:深搜每一个节点,并且进行剪枝,记录每一步上一次的s1,s2;如果之前走过的时间小于这一次,
就说明有更短的;路径,所以就不用继续遍历下去。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int a[20][20],step[20][20],tim[20][20],m,n,ans; int zz[4][2]={{-1,0},{1,0},{0,1},{0,-1}}; void dfs(int x,int y,int s1,int s2) { //cout<<"a=="<<x<<" "<<y<<" "<<a[x][y]<<endl; if(s1<=0||s2>=64) return ; if(x<=0||x>n||y<=0||y>m) return ; if(a[x][y]==0) return ; if(a[x][y]==3) { ans=min(ans,s2); return ; } if(a[x][y]==4) { s1=6; } if(step[x][y]<=s2&&tim[x][y]>=s1) return ; step[x][y]=s2; tim[x][y]=s1; for(int i=0;i<4;i++) { int tx=x+zz[i][0],ty=y+zz[i][1]; dfs(tx,ty,s1-1,s2+1); } } int main(void) { int i,j,t,sx,sy; scanf("%d",&t); while(t--) { memset(a,0,sizeof(a)); scanf("%d %d",&n,&m); for(i=1;i<=n;i++) for(j=1;j<=m;j++) { tim[i][j]=0; step[i][j]=64; scanf("%d",&a[i][j]); if(a[i][j]==2) sx=i,sy=j; } ans=64; dfs(sx,sy,6,0); if(ans==64) printf("-1 "); else printf("%d ",ans); } return 0; }
用bfs做就要简单一点。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; int ans,e[20][20],m,n; int zz[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; struct Node{ int x,y; int step,tim; }; Node tmp; void bfs() { Node tp; queue <Node> q; q.push(tmp); while(!q.empty()) { tmp=q.front(); q.pop(); for(int i=0;i<4;i++) { tp.x=tmp.x+zz[i][0]; tp.y=tmp.y+zz[i][1]; tp.step=tmp.step-1; tp.tim=tmp.tim+1; if(tp.x<=0||tp.x>n||tp.y<=0||tp.y>m||tp.step<=0) continue; if(e[tp.x][tp.y]==0) continue; //cout<<"a="<<tp.x<<" "<<tp.y<<" "<<e[tp.x][tp.y]<<endl; if(e[tp.x][tp.y]==3) { ans=tp.tim; return ; } else if(e[tp.x][tp.y]==1) { q.push(tp); } else if(e[tp.x][tp.y]==4) { tp.step=6; e[tp.x][tp.y]=1; q.push(tp); } } } } int main(void) { int t,i,j,sx,sy; scanf("%d",&t); while(t--) { scanf("%d %d",&n,&m); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { scanf("%d",&e[i][j]); if(e[i][j]==2) { tmp.x=i; tmp.y=j; tmp.step=6; tmp.tim=0; } } } //memset(vis,0,sizeof(vis)); ans=-1; bfs(); printf("%d ",ans); } return 0; }