题目链接
本题主要思路是搜索
刚开始想写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("
");
}
}
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("
");
}
}
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的偏移量在这里也很妙。