有人喜欢你,有人讨厌你;
有人在乎你,有人轻视你;
有人赞美你,有人批判你。
尊重所有的声音,但只成为自己;
不必借光而行,你我亦是星辰。
迷宫

只有一个题,迷宫,bfs模板题
假设现在我们站在一个没有传送阵的位置上,那么下一次可以延伸的方向是否如下图所示:
在这呢需要各位先学习一下队列的知识Queue(单端队列)
在不考虑传送阵的情况下,每一次入队周围4个未判断过的点
如果出现了传送阵,那么传送阵另一端的点也要加入队列(前提未经过),因为先经过的点花费的一定比后经过点要少
通过Map给每一个有传送点的位置标记,当我们走到某个位置,判断周围四个点,然后判断是否有传送阵,再判断传送阵的另一端是否经过
那么怎么计数呢?
如上图。假设红点位置为0,那么蓝点位置=红点+1;绿点位置=蓝点+1;每一次我们都添加上当前加入队列的值即可
import java.util.*;
import java.io.*;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st = new StreamTokenizer(br);
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
static int n, m;
static int[][]arr = new int[2010][2010];
static Map<String, List<int[]>> map = new HashMap<>();
static double ans = 0;
public static void main(String[] args) throws Exception {
n = nextInt();
m = nextInt();
for (int i = 0; i < m; i++) {
String[] kk = br.readLine().split(" ");
int x1 = Integer.parseInt(kk[0]), y1 = Integer.parseInt(kk[1]);
int x2 = Integer.parseInt(kk[2]), y2 = Integer.parseInt(kk[3]);
String s = x1 + ":" + y1, ss = x2 + ":" + y2;
add(s, x2, y2);
add(ss, x1, y1);
}
bfs();
pw.printf("%.2f", ans / (n * n));
pw.flush();
}
public static void bfs() {
Queue<int []> q = new LinkedList<>();
q.add(new int[] {n, n});//从终点开始往前走,走到每一个点
arr[n][n] = 0;
int xa,ya;
while (!q.isEmpty()) {//队列为空时结束
int []t=q.poll();//弹出队头
int x=t[0],y=t[1];
for(int i=-1;i<2;i+=2){//上下两边的判断
xa=x+i;
if(pd(xa,y)){
q.add(new int[]{xa,y});//加入队列
arr[xa][y]=arr[x][y]+1;//到达这一个位置的最小步数
ans+=arr[xa][y];//计数
}
}
for(int i=-1;i<2;i+=2){//左右两边的判断
ya=y+i;
if(pd(x,ya)){
q.add(new int[]{x,ya});//加入队列
arr[x][ya]=arr[x][y]+1;//到达这一个位置的最小步数
ans+=arr[x][ya];//计数
}
}
String key = x + ":" + y;
if (map.containsKey(key)) {//传送阵的判断
List<int[]> li = map.get(key);
for (int[] b: li) {
if (pd(b[0], b[1])) {
q.add(new int[] {b[0], b[1]});//加入队列
arr[b[0]][b[1]] = arr[x][y]+1;//到达这一个位置的最小步数
ans+=arr[b[0]][b[1]];//计数
}
}
}
}
}
public static void add(String key, int x, int y) {//存放传送阵
List<int[]> li = map.getOrDefault(key, new ArrayList<>());
li.add(new int[] {x, y});
map.put(key, li);
}
public static boolean pd(int x, int y) {//判断改点是否在迷宫范围内且为经过
if (x>=1&&x<=n&&y>=1&&y<=n&&arr[x][y]==0&&x*y<n*n) return true;
return false;
}
public static int nextInt() throws Exception {//int型
st.nextToken();
return (int) st.nval;
}
public static long nextLong() throws Exception {//long型
st.nextToken();
return (long) st.nval;
}
}