最少步数
时间限制:
3000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
这有一个迷宫,有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,10表示道路,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
来源
- [苗栋栋]原创 上传者
这道题有很多种做法,咱广搜写的不多(150ms),暂时只能这样啦。还可以用深搜(50ms),其中的区别这里有:http://blog.youkuaiyun.com/chao1983210400/article/details/21160245 这题其实就是求最短路径,用floyd-warshall算法也可以
import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; public class nyoj最小步数_广搜 { static int[][] c = { {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} }; static int[]dx = {-1,0,1,0}; static int[]dy = {0,-1,0,1}; static boolean [][]vis; static Queue<Integer> Q; static int x,y,Count=0; static int [][]dis ; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int s,t; int T = sc.nextInt(); while(T-->0){ s = sc.nextInt(); t = sc.nextInt(); x = sc.nextInt(); y = sc.nextInt(); vis = new boolean[9][9]; Q = new LinkedList<Integer>();Q.clear(); dis = new int[9][9]; bfs(s,t); System.out.println(dis[x][y]); } } private static void bfs(int s0,int t0) { int ps0,pt0; Q.add(s0*8+t0); while(!Q.isEmpty()){ int a = Q.poll(); ps0 = a/8; pt0 = a%8; if(ps0==x&&pt0==y)return ; vis[ps0][pt0] = true; for(int i=0; i<4; i++){ s0 = ps0+dx[i]; t0 = pt0+dy[i]; if(s0>=0&&s0<=8 && t0>=0&&t0<=8) if(!vis[s0][t0] && c[s0][t0]!=1){ dis[s0][t0] = dis[ps0][pt0] +1; if(s0==x&&t0==y)return ; vis[s0][t0]=true; Q.add(s0*8+t0); } } } } }
FloydWarshall算法
#include<iostream> #include<cmath> using namespace std; int mz[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 }; inline int ABS(int a) { return a>0?a:-a; } int len[10][10][10][10]; const int INF=100000; void FloydWarshall() { for(int i=1;i!=8;i++) for(int j=1;j!=8;j++) for(int k=1;k!=8;k++) for(int l=1;l!=8;l++) if(i==k && j== l) len[i][j][k][l]=0; else if(mz[i][j]==0 && mz[k][l]==0 && ABS(i-k)+ABS(j-l)==1) len[i][j][k][l]=1; else len[i][j][k][l]=INF; int v=49; for(int k=1;k!=8;k++) for(int l=1;l!=8;l++) for(int m=1;m!=8;m++) for(int n=1;n!=8;n++) for(int i=1;i!=8;i++) for(int j=0;j!=8;j++) if(len[m][n][i][j]>len[m][n][k][l]+len[k][l][i][j]) len[m][n][i][j]=len[m][n][k][l]+len[k][l][i][j]; } int main() { FloydWarshall(); int n,a,b,c,d; cin>>n; while(n--) { cin>>a>>b>>c>>d; cout<<len[a][b][c][d]<<endl; } }
-
第一行输入一个整数n(0<n<=100),表示有n组测试数据;