[ABC272D] Root M Leaper 题解
题意
你每步可以走
Solution
很明显,这是一道 dfs 或 bfs,但是 dfs 会重复算很多遍,时间复杂度是错的,所以只能用 bfs。
根据题目,
我们不需要对于每个节点都计算出可以向哪里走,只需要一个初始化算出 dfs 或 bfs 模板中所需的偏移量
那我们直接
如果有和我一样不知道为啥接着找而不是 break 的同学,看这里。
那还有一个问题,万一我找不到怎么办?没有符合要求的
记录完
#include<bits/stdc++.h>
using namespace std;
struct node
{
int x , y;
};
queue<node> q;
int n , m;
bool flag = false; // 是否能走出去
int a , b;
int cnt = 0; // 每一步有几种走法
int dx[100010] , dy[100010]; // 偏移量,100000个 应该够了吧
int ans[410][410]; // 走到每个点所需的最小步数
bool in(int x , int y) // 是否在边界内
{
return x <= n && x >= 1 && y <= n && y >= 1;
}
void bfs() // 正常bfs,不解释
{
q.push({1 , 1});
ans[1][1] = 0;
while(!q.empty())
{
node tmp = q.front();
q.pop();
for(int i = 1 ; i <= cnt ; i ++)
{
int nx = tmp.x + dx[i];
int ny = tmp.y + dy[i];
if(in(nx , ny) && ans[nx][ny] > ans[tmp.x][tmp.y] + 1)
{
ans[nx][ny] = ans[tmp.x][tmp.y] + 1;
q.push({nx , ny});
}
}
}
}
void init() // 每一步的走法
{
// x+ , y+
dx[++ cnt] = a;
dy[cnt] = b;
// x+ , y-
dx[++ cnt] = a;
dy[cnt] = -1 * b;
// x- , y+
dx[++ cnt] = -1 * a;
dy[cnt] = b;
// x- , y-
dx[++ cnt] = -1 * a;
dy[cnt] = -1 * b;
}
int main()
{
scanf("%d%d" , &n , &m);
for(int i = 0 ; i <= n ; i ++)
{
for(int j = 0 ; j <= n ; j ++)
{
if(i * i + j * j == m)
{
a = i; // 行数 + a
b = j; // 列数 + b
init(); // 进行dx,dy的
flag = true; // 有可以走的地方啦qwq
}
}
}
if(!flag) // 走不出去力(悲
{
for(int i = 1 ; i <= n ; i ++)
{
for(int j = 1 ; j <= n ; j ++)
{
if(i == 1 && j == 1) printf("0 "); // 初始点
else printf("-1 "); // 除了初始点,都是-1
}
printf("\n");
}
return 0;
}
memset(ans , 0x3f , sizeof(ans));
ans[1][1] = 0;
bfs();
for(int i = 1 ; i <= n ; i ++)
{
for(int j = 1 ; j <= n ; j ++)
printf("%d " , ans[i][j] == 0x3f3f3f3f ? -1 : ans[i][j]); // 有的地方由于特殊原因哪怕可以走,也到不了,所以需要特判一下qwq
printf("\n");
}
return 0;
}