[DFS]迷宫最小步数
描述
这有一个迷宫,有0~8行和0~8列:
 1,1,1,1,1,1,1,1,1
 1,0,0,1,0,0,1,0,1
 1,0,0,1,1,0,0,0,1
 1,0,1,0,1,1,0,1,1
 1,0,0,0,0,1,0,0,1
 1,1,0,1,0,1,0,0,1
 1,1,0,1,0,1,0,0,1
 1,1,0,1,0,0,0,0,1
 1,1,1,1,1,1,1,1,1
0表示道路,1表示墙。
现在输入一个道路的坐标作为起点,再如输入一个道路的坐标作为终点,问最少走几步才能从起点到达终点?
(注:一步是指从一坐标点走到其上下左右相邻坐标点,如:从(3,1)到(4,1)。)
- 输入
- 第一行输入一个整数n(0<n<=100),表示有n组测试数据;
 随后n行,每行有四个整数a,b,c,d(0<=a,b,c,d<=8)分别表示起点的行、列,终点的行、列。
- 输出
- 输出最少走几步。
- 样例输入
- 
2 3 1 5 7 3 1 6 7 
- 样例输出
- 
12 11 
- 
//深搜,遍历上下所有点找出最 ======================================== // dfs #include <stdio.h> int step,x,y,ex,ey; bool vis[9][9],map[9][9]={ //设置两个迷宫数组 1,1,1,1,1,1,1,1,1, 1,0,0,1,0,0,1,0,1, 1,0,0,1,1,0,0,0,1, 1,0,1,0,1,1,0,1,1, 1,0,0,0,0,1,0,0,1, 1,1,0,1,0,1,0,0,1, 1,1,0,1,0,1,0,0,1, 1,1,0,1,0,0,0,0,1, 1,1,1,1,1,1,1,1,1 }; void dfs(int i,int j,int cnt) { if(i<0||i>8||j<0||j>8||vis[i][j]||map[i][j]||cnt>=step) return; if(i==ex&&j==ey) { step=cnt; //到达终点 return; } vis[i][j]=1; // 这个已经走过了 dfs(i,j-1,cnt+1); //左 ,每走一步,cnt+1 dfs(i-1,j,cnt+1); //上 dfs(i,j+1,cnt+1); //右 dfs(i+1,j,cnt+1); //下 vis[i][j]=0; } int main() { int n; scanf("%d",&n); while(n--) { scanf("%d%d%d%d",&x,&y,&ex,&ey); step=100; dfs(x,y,0); //初始化0 printf("%d\n",step); } return 0; }相关1:题目不变,问有多少种走法。 #include <stdio.h> int a[8][8]; //既是图形数组也是标记数组 int count; int m,n; void dfs(int i,int j) { if(i == n-1 && j == m-1) //出口,到达终点 { count ++ ; return ; } a[i][j] = 1; //标记 if(i > 0 && !a[i - 1][j]) dfs(i - 1,j); //向上移动(条件:a[i][j]能向上通过并且为被标记,以下同理) if(i < n - 1 && !a[i + 1][j]) dfs(i + 1,j); //下 if(j > 0 && !a[i][j - 1]) dfs(i,j - 1); //左 if(j < m - 1 && !a[i][j + 1]) dfs(i,j + 1); //右 a[i][j] = 0; } int main() { int T; scanf("%d",&T); while(T -- ) { int i,j; count = 0; scanf("%d%d",&n,&m); for(i = 0;i < n;i ++ ) for(j = 0;j < m;j ++ ) scanf("%d",&a[i][j]); dfs(0,0); printf("%d\n",count); } return 0; }相关2:题目变动为可以朝八个方向走,问有多少种走法? #include<iostream> #include<cstdio> #include<cstring> using namespace std; int sx[8]={0,0,1,1,1,-1,-1,-1};//八个方向,初始化赋好值 int sy[8]={1,-1,0,1,-1,0,1,-1}; int n,i,j,ans=0; int a[100][100],b[100][100]; void dfs(int s,int t) { int i,x,y; if (s==1&&t==n)//如果到达终点,方案数+1 { ans++; return; } for (i=0;i<8;++i)//枚举八个方向 { x=s+sx[i]; y=t+sy[i]; if (x>0&&y>0&&x<=n&&y<=n&&a[x][y]==0&&b[x][y]==0)//前四个条件是判断是否越界,最后一个是判断是否访问 { //过 b[x][y]=1; dfs(x,y); b[x][y]=0; } } return; } int main() { scanf("%d",&n); for (i=1;i<=n;++i) for (j=1;j<=n;++j) scanf("%d",&a[i][j]); b[1][1]=1; //b[i][j]表示坐标为(i,j)这个点有没有被访问过 dfs(1,1); printf("%d",ans); return 0; }相关3:有一个X*Y的网格,小团要在此网格上从左上角到右下角,只能走格点且只能向右或向下走。请设计一个算法,计算小团有多少种走法。给定两个正整数int x,int y,请返回一共有多少种不同的走法。 for(int i = 0; i <= m; i++) { dp[i][0] = 1; } for(int i = 0; i <= n; i++) { dp[0][i] = 1; } for(int i = 1; i <= m; i++) { for(int j = 1; j <= n; j++) { dp[i][j] = dp[i-1][j] + dp[i][j-1]; } } cout<<dp[m][n];
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号