解题思路
这题主要就是写个裸的广度优先遍历。我在看了数据量之后果断选择了手写队列,加输入挂,奈何还是不行,其实动脑子都知道主要是要开输出挂。在开了输出挂之后就全过掉了。
代码
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
public class Main {
public static class FastScanner{
private BufferedReader br;
private StringTokenizer st;
public FastScanner() {
br = new BufferedReader(new InputStreamReader(System.in));
}
public String nextToken() {
while(st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (Exception e) {
e.printStackTrace();
}
}
return st.nextToken();
}
public int nextInt() {
return Integer.valueOf(nextToken());
}
}
static int N, M;
static int sx, sy;
static boolean[][] visited;
static int[][] steps;
static int[] dx = {-2, -2, -1, -1, 1, 1, 2, 2};
static int[] dy = {-1, 1, -2, 2, -2, 2, -1, 1};
static int[] qx = new int[200000];
static int[] qy = new int[200000];
public static void main(String[] args) {
FastScanner fs = new FastScanner();
PrintWriter writer = new PrintWriter(System.out);
N = fs.nextInt();
M = fs.nextInt();
visited = new boolean[N+1][M+1];
steps = new int[N+1][M+1];
for(int i = 1; i <= N; i++) {
for(int j = 1; j <= M; j++) {
visited[i][j] = false;
steps[i][j] = 0;
}
}
sx = fs.nextInt();
sy = fs.nextInt();
int l, r;
l = r = 0;
visited[sx][sy] = true;
qx[r] = sx;
qy[r] = sy;
while(l <= r) {
int tx = qx[l];
int ty = qy[l];
for(int i = 0; i < 8; i++) {
int nx = tx + dx[i];
int ny = ty + dy[i];
if(1 <= nx && nx <= N && 1 <= ny && ny <= M) {
if(!visited[nx][ny]) {
visited[nx][ny] = true;
steps[nx][ny] = steps[tx][ty] + 1;
qx[++r] = nx;
qy[r] = ny;
}
}
}
l++;
}
for(int i = 1; i <= N; i++) {
for(int j = 1; j <= M; j++) {
if(visited[i][j]) {
writer.printf("%-5d", steps[i][j]);
} else {
writer.printf("%-5d", -1);
}
}
writer.println();
}
writer.close();
}
}