luoguP1443馬的遍歷
阿新 • • 發佈:2020-10-13
題目連結
本題主要思路是搜尋
剛開始想寫bfs,寫著寫著就寫假了寫成了dfs
dfs會TLE成80分
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N = 410; int n, m; int ans[N][N]; bool book[N][N]; int dx[8] = {2, 1, 1, 2, -1, -1, -2, -2}; int dy[8] = {1, -2, 2, -1, 2, -2, 1, -1}; void bfs(int x, int y, int d) { if(x < 1 || y < 1 || x > n || y > m || (ans[x][y] != -1 && ans[x][y] <= d)) return; // q.push({x, y}); book[x][y] = 1; if(ans[x][y] != -1)ans[x][y] = min(ans[x][y], d); else ans[x][y] = d; for(int i = 0 ; i < 8 ; i ++) { bfs(x + dx[i], y + dy[i], d + 1); } return; } void print() { for(int i = 1; i <= n ; i ++) { for(int j = 1; j <= m ; j ++) { printf("%-5d", ans[i][j]); } printf("\n"); } } int main () { int a, b; scanf("%d%d%d%d", &n, &m, &a, &b); for(int i = 1; i <= n ; i ++) { for(int j = 1; j <= m ; j ++) { ans[i][j] = -1; } } bfs(a, b, 0); print(); return 0; }
而且這個裡面的book陣列沒有用到
值得一提的是:這道題的輸入輸出非常重要
題目要求左對齊,寬五格
我:printf("%d(+五個空格)", ...);
--> 0分
看了看題目是四個空格,於是把五個空格改成了四個空格,20分。
看了題解是printf("%-5d", ...);
80分。(以前wa的點全都ac,剩下的就是tle了)
真就離譜。
接下來開始想正解
bfs,肯定要用到佇列。
-
先將出初始狀態入隊,列舉這個狀態所有可能的狀態,修改答案。
-
將當前狀態出隊,列舉到的可能狀態入隊,然後繼續列舉接下來的狀態。
-
如果列舉到了一個狀態,我們先前已經列舉過了,現在就不用枚舉了,直接
continue
這也是廣度優先搜尋(寬搜bfs)的一條重要性質。
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N = 410; int n, m; int ans[N][N]; bool book[N][N]; int dx[8] = {2, 1, 1, 2, -1, -1, -2, -2}; int dy[8] = {1, -2, 2, -1, 2, -2, 1, -1}; typedef pair<int, int> PII; void bfs(int x, int y, int d) { ans[x][y] = d; book[x][y] = 1; queue<PII> q; q.push({x, y}); while(q.size()) { PII top = q.front(); q.pop(); int fx = top.first, fy = top.second; for(int i = 0 ; i < 8 ; i ++) { int nx = fx + dx[i], ny = fy + dy[i]; if(nx < 1 || ny < 1 || nx > n || ny > m || book[nx][ny]) continue; top.first = nx, top.second = ny; q.push(top); book[nx][ny] = 1; ans[nx][ny] = ans[fx][fy] + 1; } } } void print() { for(int i = 1; i <= n ; i ++) { for(int j = 1; j <= m ; j ++) { printf("%-5d", ans[i][j]); } printf("\n"); } } int main () { int a, b; scanf("%d%d%d%d", &n, &m, &a, &b); for(int i = 1; i <= n ; i ++) { for(int j = 1; j <= m ; j ++) { ans[i][j] = -1; } } bfs(a, b, 0); print(); return 0; }
AC程式碼簡單易懂。
dx,dy的偏移量在這裡也很妙。