题解 P1443 [马的遍历]
题目描述
有一个n*m的棋盘(1<n,m<=400),在某个点上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步
输入格式
一行四个数据,棋盘的大小和马的坐标
输出格式
一个n*m的矩阵,代表马到达某个点最少要走几步(左对齐,宽5格,不能到达则输出-1)
输入输出样例
输入 #1
3 3 1 1
输出 #1
0 3 2
3 -1 1
2 1 4
这道题用广搜和深搜写都能过,但是用深搜写要剪剪枝
code:
dfs:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for (long long i = a; i <= b; ++i) 3 #define ll long long 4 #define N 410 5 using namespace std; 6 7 ll n, m, mx, my, dx[10] = {0, 2, 2, 1, -1, -2, -2, 1, -1}, dy[10] = {0, 1, -1, 2, 2, -1, 1, -2, -2}, ans[N][N]; 8 9 inline ll read(){ 10 ll s = 0, w = 1; 11 char ch = getchar(); 12 while (ch < '0' || ch > '9'){ 13 if (ch == '-') w *= -1; 14 ch = getchar(); 15 } 16 while (ch >= '0' && ch <= '9'){ 17 s = s * 10 + ch - '0'; 18 ch = getchar(); 19 } 20 return s * w; 21 } 22 23 inline void dfs(ll x, ll y, ll z){ 24 if (z > 200) return ; //不可少,除非你想超时 25 ans[x][y] = z; //记答案 26 REP(i, 1, 8){ 27 ll fx = x + dx[i], fy = y + dy[i]; //尝试扩展 28 if (fx > 0 && fx <= n && fy > 0 && fy <= m && (ans[fx][fy] == -1 || ans[fx][fy] > z + 1)) dfs(fx, fy, z + 1); //合格则搜下去 29 } 30 } 31 32 inline void work(){ 33 n = read(), m = read(), mx = read(), my = read(); 34 memset(ans, -1, sizeof(ans)); //把ans数组赋值为-1 35 dfs(mx, my, 0); //广搜 36 REP(i, 1, n){ 37 REP(j, 1, m) printf("%-5lld", ans[i][j]); //注意格式,我就被卡过1次 38 puts(""); 39 } 40 } 41 42 int main(){ 43 work(); 44 return 0; 45 }
bfs:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for (long long i = a; i <= b; ++i) 3 #define ll long long 4 #define N 410 5 using namespace std; 6 7 ll n, m, mx, my, dx[10] = {0, 1, 1, -1, -1, 2, 2, -2, -2}, dy[10] = {0, 2, -2, 2, -2, 1, -1, 1, -1}, ans[N][N]; 8 9 queue < ll > qx, qy; 10 11 inline ll read(){ //输入 12 ll s = 0, w = 1; 13 char ch = getchar(); 14 while (ch < '0' || ch > '9'){ 15 if (ch == '-') w *= -1; 16 ch = getchar(); 17 } 18 while (ch >= '0' && ch <= '9'){ 19 s = s * 10 + ch - '0'; 20 ch = getchar(); 21 } 22 return s * w; 23 } 24 25 inline void bfs(ll xx, ll yy){ 26 ans[xx][yy] = 0; //记答案 27 qx.push(xx), qy.push(yy); //入队 28 while (!qx.empty() && !qy.empty()){ //队列非空 29 ll x = qx.front(), y = qy.front(); //取队首 30 qx.pop(), qy.pop(); //弹出队首 31 REP(i, 1, 8){ 32 ll fx = x + dx[i], fy = y + dy[i]; //尝试扩展 33 if (fx < 1 || fx > n || fy < 1 || fy > m || ans[fx][fy] >= 0) continue; //不够格则跳过 34 ans[fx][fy] = ans[x][y] + 1; //记答案 35 qx.push(fx), qy.push(fy); //入队 36 } 37 } 38 } 39 40 inline void work(){ 41 n = read(), m = read(), mx = read(), my = read(); 42 memset(ans, -1, sizeof(ans)); //把ans数组赋值为-1 43 bfs(mx, my); //广搜 44 REP(i, 1, n){ 45 REP(j, 1, m) printf("%-5lld", ans[i][j]); //注意格式,我就被卡过1次 46 puts(""); 47 } 48 } 49 50 int main(){ 51 work(); 52 return 0; 53 }