diff --git "a/ACWing/src/BFS/\347\237\251\351\230\265\350\267\235\347\246\273.java" "b/ACWing/src/BFS/\347\237\251\351\230\265\350\267\235\347\246\273.java" new file mode 100644 index 0000000000000000000000000000000000000000..30cfedfa8df6b1baeeed3a80fd89cbdde070a3a4 --- /dev/null +++ "b/ACWing/src/BFS/\347\237\251\351\230\265\350\267\235\347\246\273.java" @@ -0,0 +1,112 @@ +package BFS; + +import java.io.*; +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.Scanner; +import java.util.StringTokenizer; + +import static java.lang.System.in; + +/** + * 多源bfs + * 173. 矩阵距离 + * 给定一个N行M列的01矩阵A,A[i][j] 与 A[k][l] 之间的曼哈顿距离定义为: + * dist(A[i][j],A[k][l])=|i−k|+|j−l| + * 输出一个N行M列的整数矩阵B,其中: + * B[i][j]=min1≤x≤N,1≤y≤M,A[x][y]=1dist(A[i][j],A[x][y]) + * 输入格式 + * 第一行两个整数n,m。 + * 接下来一个N行M列的01矩阵,数字之间没有空格。 + * 输出格式 + * 一个N行M列的矩阵B,相邻两个整数之间用一个空格隔开。 + * 数据范围 + * 1≤N,M≤1000 + * 输入样例: + * 3 4 + * 0001 + * 0011 + * 0110 + * 输出样例: + * 3 2 1 0 + * 2 1 0 0 + * 1 0 0 1 + */ +public class 矩阵距离 { + static class node { + int x, y; + + public node(int x, int y) { + this.x = x; + this.y = y; + } + } + + public static void main(String[] args) throws IOException { + Scanner sc = new Scanner(System.in); + n = nextInt(); + m = nextInt(); + + for (int i = 0; i < n; i++) { + g[i] = next().toCharArray(); + } + + ArrayDeque q = new ArrayDeque(); + for (int i = 0; i < n; i++) { + Arrays.fill(dis[i], -1); + for (int j = 0; j < m; j++) { + if (g[i][j] == '1') { + q.add(new node(i, j)); + dis[i][j] = 0; + } + } + } + + while (!q.isEmpty()) { + node p = q.poll(); + for (int i = 0; i < 4; i++) { + int x = p.x + dir[i][0], y = dir[i][1]+p.y; + if (x < 0 || x >= n || y < 0 || y >= m||dis[x][y]!=-1) continue; + dis[x][y] = dis[p.x][p.y] + 1; + q.add(new node(x, y)); + } + } + + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + bw.write(dis[i][j]+""); + } + bw.write("\n"); + } + bw.flush(); + + } + + static int[][] dir = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + static int n, m, N = 1010; + static char[][] g = new char[N][N]; + static int[][] dis = new int[N][N]; + static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); + static BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + static StringTokenizer tokenizer = new StringTokenizer(""); + + static String nextLine() throws IOException {// 读取下一行字符串 + return reader.readLine(); + } + + static String next() throws IOException {// 读取下一个字符串 + while (!tokenizer.hasMoreTokens()) { + //如果没有字符了,就是下一个,使用空格拆分, + tokenizer = new StringTokenizer(reader.readLine()); + } + return tokenizer.nextToken(); + } + + static int nextInt() throws IOException {// 读取下一个int型数值 + return Integer.parseInt(next()); + } + + static double nextDouble() throws IOException {// 读取下一个double型数值 + return Double.parseDouble(next()); + } +} diff --git "a/ACWing/src/DFS/floodfill/\345\237\216\345\240\241\351\227\256\351\242\230.java" "b/ACWing/src/DFS/floodfill/\345\237\216\345\240\241\351\227\256\351\242\230.java" new file mode 100644 index 0000000000000000000000000000000000000000..8b536af2d306b1f704937454f5664d26a9820601 --- /dev/null +++ "b/ACWing/src/DFS/floodfill/\345\237\216\345\240\241\351\227\256\351\242\230.java" @@ -0,0 +1,70 @@ +package DFS.floodfill; + +import java.util.ArrayDeque; +import java.util.Scanner; + +/** + * https://blog.csdn.net/qq_30277239/article/details/104670312 + * 显然寻找有多少个四联通块 + * 并找出最大连通块有多少个 + */ +public class 城堡问题 { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + n = sc.nextInt(); + m = sc.nextInt(); + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + g[i][j] = sc.nextInt(); + } + } + int cnt = 0, area = 0; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (!vis[i][j]) { + area = Math.max(bfs(i, j), area); + cnt++; + } + } + } + System.out.println(cnt); + System.out.println(area); + } + + private static int bfs(int x, int y) { + int area = 0; + q.clear(); + q.add(x * m + y); + while (!q.isEmpty()) { + int p = q.poll(); + x = p / m; + y = p % m; + area++; + vis[x][y] = true; + for (int i = 0; i < 4; i++) { + int a = x + dir[i][0], b = y + dir[i][1]; + if (a < 0 || a >= n || b < 0 || b >= m || vis[a][b]) continue; + if ((g[x][y] >> i & 1) == 1) continue; + q.add(a * m + b); + } + } + return area; + } + + static void dfs(int x, int y) { + ans++; + vis[x][y] = true; + for (int i = 0; i < 4; i++) { + int a = x + dir[i][0], b = y + dir[i][1]; + if (a < 0 || a >= n || b < 0 || b >= m || vis[a][b]) continue; + if ((g[x][y] >> i & 1) == 1) continue; + dfs(a, b); + } + } + + static int[][] dir = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}}; + static int[][] g = new int[51][51]; + static boolean[][] vis = new boolean[51][51]; + static ArrayDeque q = new ArrayDeque(); + static int n, m, ans; +} diff --git "a/ACWing/src/DFS/floodfill/\345\261\261\345\263\260\345\222\214\345\261\261\350\260\267.java" "b/ACWing/src/DFS/floodfill/\345\261\261\345\263\260\345\222\214\345\261\261\350\260\267.java" new file mode 100644 index 0000000000000000000000000000000000000000..217851f6e020aee7562a40be58916b6975c53753 --- /dev/null +++ "b/ACWing/src/DFS/floodfill/\345\261\261\345\263\260\345\222\214\345\261\261\350\260\267.java" @@ -0,0 +1,68 @@ +package DFS.floodfill; + +import java.util.ArrayDeque; +import java.util.Scanner; + +/** + * https://blog.csdn.net/qq_30277239/article/details/104671983 + * 显然bfs过程中寻找, + * 如果该联通块没有比当前位置数更小的就是山谷 + * 如果该联通块没有比当前位置数更大的就是山峰 + * 打上标记,如果都有,则是山坡不计算... + */ +public class 山峰和山谷 { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + n = sc.nextInt(); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + g[i][j] = sc.nextInt(); + } + } + int peak = 0, valley = 0;//山峰,山谷 + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (!vis[i][j]) { + High = false; + low = false; + bfs(i, j); + if (!High && !low) ; + else if (!High) peak++; + else if (!low) valley++; + } + } + } + System.out.println(peak); + System.out.println(valley); + } + + static void bfs(int x, int y) { + q.add(x * n + y); + int t = g[x][y]; + while (!q.isEmpty()) { + int p = q.poll(); + x = p / n; + y = p % n; + vis[x][y] = true; + for (int i = -1; i < 2; i++) {//八联通 + for (int j = -1; j < 2; j++) { + if (i == 0 && j == 0) continue; + int a = x + i, b = y + j; + if (a < 0 || a >= n || b < 0 || b >= n) continue; + if (g[x][y] != g[a][b]) { + if (g[a][b] > g[x][y]) High = true; + else if (g[a][b] < g[x][y]) low = true; + } else if (!vis[a][b]) { + q.add(a * n + b); + } + } + } + } + } + + static ArrayDeque q = new ArrayDeque(); + static boolean High = false, low = false; + static int n; + static int[][] g = new int[1010][1010]; + static boolean[][] vis = new boolean[1010][1010]; +} diff --git "a/ACWing/src/DFS/floodfill/\346\261\240\345\241\230\350\256\241\346\225\260.java" "b/ACWing/src/DFS/floodfill/\346\261\240\345\241\230\350\256\241\346\225\260.java" new file mode 100644 index 0000000000000000000000000000000000000000..d19d576f5bc3334dffdd92189a274a1ae9eb7e4a --- /dev/null +++ "b/ACWing/src/DFS/floodfill/\346\261\240\345\241\230\350\256\241\346\225\260.java" @@ -0,0 +1,92 @@ +package DFS.floodfill; + +import java.util.ArrayDeque; +import java.util.Scanner; + +/** + * 农夫约翰有一片 N∗M 的矩形土地。 + * 最近,由于降雨的原因,部分土地被水淹没了。 + * 现在用一个字符矩阵来表示他的土地。 + * 每个单元格内,如果包含雨水,则用”W”表示,如果不含雨水,则用”.”表示。 + * 现在,约翰想知道他的土地中形成了多少片池塘。 + * 每组相连的积水单元格集合可以看作是一片池塘。 + * 每个单元格视为与其上、下、左、右、左上、右上、左下、右下八个邻近单元格相连。 + * 请你输出共有多少片池塘,即矩阵中共有多少片相连的”W”块。 + * 输入格式 + * 第一行包含两个整数 N 和 M。 + * 接下来 N 行,每行包含 M 个字符,字符为”W”或”.”,用以表示矩形土地的积水状况,字符之间没有空格。 + * 输出格式 + * 输出一个整数,表示池塘数目。 + * 数据范围 + * 1≤N,M≤1000 + * 输入样例: + * 10 12 + * W........WW. + * .WWW.....WWW + * ....WW...WW. + * .........WW. + * .........W.. + * ..W......W.. + * .W.W.....WW. + * W.W.W.....W. + * .W.W......W. + * ..W.......W. + * 输出样例: + * 3 + * 求几个八联通块 + */ +public class 池塘计数 { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + n = sc.nextInt(); + m = sc.nextInt(); + for (int i = 0; i < n; i++) { + g[i] = sc.next().toCharArray(); + } + int ans = 0; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (g[i][j] == 'W') { + bfs(i, j); + ans++; + } + } + } + System.out.println(ans); + } + + static void dfs(int x, int y) { + g[x][y] = '.'; + for (int i = -1; i < 2; i++) { + for (int j = -1; j < 2; j++) { + if (i == j && j == 0) continue; + int a = x + i, b = y + j; + if (a < 0 || a >= n || b < 0 || b >= m || g[a][b] == '.') continue; + dfs(a, b); + } + } + } + + static void bfs(int x, int y) { + ArrayDeque q = new ArrayDeque(); + int t = x * m + y; + q.add(t); + while (!q.isEmpty()) { + Integer w = q.poll(); + x = w / m; + y = w % m; + g[x][y] = '.'; + for (int i = -1; i < 2; i++) { + for (int j = -1; j < 2; j++) { + if (i == j && j == 0) continue; + int a = x + i, b = y + j; + if (a < 0 || a >= n || b < 0 || b >= m || g[a][b] == '.') continue; + dfs(a, b); + } + } + } + } + + static char[][] g = new char[1010][1001]; + static int n, m; +} diff --git "a/ACWing/src/DFS/floodfill/\350\277\267\345\256\253\351\227\256\351\242\230.java" "b/ACWing/src/DFS/floodfill/\350\277\267\345\256\253\351\227\256\351\242\230.java" new file mode 100644 index 0000000000000000000000000000000000000000..55b8b34b5b686f567ed0b8eafcb9d020eb55e375 --- /dev/null +++ "b/ACWing/src/DFS/floodfill/\350\277\267\345\256\253\351\227\256\351\242\230.java" @@ -0,0 +1,58 @@ +package DFS.floodfill; + +import java.util.ArrayDeque; +import java.util.Scanner; + +/** + * https://blog.csdn.net/qq_30277239/article/details/104672658 + * 不能使用数字代表方阵坐标, + * 只能矩阵坐标 + * 显然bfs寻路问题,记录路径,从终点往起点走 + */ +public class 迷宫问题 { + static class node { + int x, y; + + public node(int x, int y) { + this.x = x; + this.y = y; + } + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + n = sc.nextInt(); + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= n; j++) { + g[i][j] = sc.nextInt(); + } + } + ArrayDeque q = new ArrayDeque(); + int[][] dir = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + q.add(new node(n - 1, n - 1)); + int x = 0, y = 0, a, b; + while (!q.isEmpty()) { + node p = q.poll(); + vis[p.x][p.y] = true; + for (int i = 0; i < 4; i++) { + a = dir[i][0] + p.x; + b = dir[i][1] + p.y; + if (a < 0 || a >= n || b < 0 || b >= n || vis[a][b] || g[a][b] == 1) continue; + q.add(new node(a, b)); + pre[a][b] = p; + if (a == 0 && b == 0) break; + } + } + node p = pre[0][0]; + while (true) { + System.out.println(p.x + " " + p.y); + if (p.x == n - 1 && p.y == n - 1) break; + p = pre[p.x][p.y]; + } + } + + static int n; + static boolean[][] vis = new boolean[1010][1010]; + static node[][] pre = new node[1010][1010]; + static int[][] g = new int[1010][1010]; +} diff --git "a/ACWing/src/DFS/\346\234\200\347\237\255\350\267\257/\346\212\223\344\275\217\351\202\243\345\244\264\347\211\233.java" "b/ACWing/src/DFS/\346\234\200\347\237\255\350\267\257/\346\212\223\344\275\217\351\202\243\345\244\264\347\211\233.java" new file mode 100644 index 0000000000000000000000000000000000000000..53d57ff4bf2f8ff57f426df4c81b58fdee787fb5 --- /dev/null +++ "b/ACWing/src/DFS/\346\234\200\347\237\255\350\267\257/\346\212\223\344\275\217\351\202\243\345\244\264\347\211\233.java" @@ -0,0 +1,48 @@ +package DFS.最短路; + +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.Scanner; + +/** + * https://blog.csdn.net/qq_30277239/article/details/104680308 + * bfs + * 显然边界问题 + * n*2不会超过20w+10 + * n-1不会低于0 + * 如果越界则无需记录 + */ +public class 抓住那头牛 { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + n = sc.nextInt(); + k = sc.nextInt(); + ArrayDeque q = new ArrayDeque(); + Arrays.fill(d, -1); + d[n] = 0; + q.add(n); + while (!q.isEmpty()) { + int t = q.poll(); + if (t == k) { + System.out.println(d[t]); + break; + } + if (t + 1 < N && d[t + 1] == -1) { + d[t + 1] = d[t] + 1; + q.add(t + 1); + } + if (t - 1 >= 0 && d[t - 1] == -1) { + d[t - 1] = d[t] + 1; + q.add(t - 1); + } + if (t * 2 < N && d[t * 2] == -1) { + q.add(t * 2); + d[t * 2] = d[t] + 1; + } + } + } + + static int N = 201000; + static int[] d = new int[N]; + static int n, k; +} diff --git "a/ACWing/src/DFS/\346\234\200\347\237\255\350\267\257/\346\255\246\345\243\253\351\243\216\345\272\246\347\232\204\347\211\233.java" "b/ACWing/src/DFS/\346\234\200\347\237\255\350\267\257/\346\255\246\345\243\253\351\243\216\345\272\246\347\232\204\347\211\233.java" new file mode 100644 index 0000000000000000000000000000000000000000..f9bbb26dace0e6b433d8d20db7c4fe87caf0b77b --- /dev/null +++ "b/ACWing/src/DFS/\346\234\200\347\237\255\350\267\257/\346\255\246\345\243\253\351\243\216\345\272\246\347\232\204\347\211\233.java" @@ -0,0 +1,53 @@ +package DFS.最短路; + +import java.util.ArrayDeque; +import java.util.Scanner; + +/** + * https://blog.csdn.net/qq_30277239/article/details/104675982 + * 马走日bfs寻最短路 + */ +public class 武士风度的牛 { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + m = sc.nextInt(); + n = sc.nextInt(); + for (int i = 0; i < n; i++) { + g[i] = sc.next().toCharArray(); + } + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (g[i][j] == 'K') { + System.out.println(bfs(i, j)); + } + } + } + + } + + static int bfs(int x, int y) { + ArrayDeque q = new ArrayDeque(); + q.add(x * m + y); + int a, b; + while (!q.isEmpty()) { + int p = q.poll(); + x = p / m; + y = p % m; + g[x][y] = '*'; + for (int i = 0; i < 8; i++) { + a = x + dir[i][0]; + b = y + dir[i][1]; + if (a < 0 || a >= n || b < 0 || b >= m || g[a][b] == '*') continue; + if (g[a][b] == 'H') return dis[x][y] + 1; + q.add(a * m + b); + dis[a][b] = dis[x][y] + 1; + } + } + return -1; + } + + static int[][] dir = {{-2, 1}, {-1, 2}, {1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}, {-2, -1}}; + static char[][] g = new char[160][160]; + static int n, m; + static int[][] dis = new int[200][200]; +} diff --git "a/ACWing/src/DFS/\346\234\200\347\237\255\350\267\257/\351\251\254\350\265\260\346\227\245.java" "b/ACWing/src/DFS/\346\234\200\347\237\255\350\267\257/\351\251\254\350\265\260\346\227\245.java" new file mode 100644 index 0000000000000000000000000000000000000000..528e9093d519e8cd88dc94c04f79c271bb627397 --- /dev/null +++ "b/ACWing/src/DFS/\346\234\200\347\237\255\350\267\257/\351\251\254\350\265\260\346\227\245.java" @@ -0,0 +1,48 @@ +package DFS.最短路; + +import java.util.Arrays; +import java.util.Scanner; + +/** + * 1 + * 5 4 0 0 + */ +public class 马走日 { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + t = sc.nextInt(); + while (t-- != 0) { + n = sc.nextInt(); + m = sc.nextInt(); + x = sc.nextInt(); + y = sc.nextInt(); + ans = 0; + for (int i = 0; i < vis.length; i++) { + Arrays.fill(vis[i], false); + } + vis[x][y] = true; + dfs(x, y, 1); + System.out.println(ans); + } + } + + static void dfs(int x, int y, int cnt) { + if (cnt == n * m) { + ans++; + return; + } + + for (int i = 0; i < 8; i++) { + int a = x + dir[i][0], b = y + dir[i][1]; + if (a < 0 || a >= n || b < 0 || b >= m || vis[a][b]) continue; + vis[a][b] = true; + dfs(a, b, cnt + 1); + vis[a][b] = false; + } + } + + static int t, n, m, x, y, ans; + static boolean[][] vis = new boolean[10][10]; + static int[][] dir = {{-2, 1}, {-1, 2}, {1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}, {-2, -1}}; + +} diff --git "a/ACWing/src/DFS/\346\240\221\347\232\204\351\207\215\345\277\203.java" "b/ACWing/src/DFS/\346\240\221\347\232\204\351\207\215\345\277\203.java" index 767679cc438b4fc4533ec521e9c36d4fd63f50c0..ad67041a00b470c5260b8815437a073ee5930a67 100644 --- "a/ACWing/src/DFS/\346\240\221\347\232\204\351\207\215\345\277\203.java" +++ "b/ACWing/src/DFS/\346\240\221\347\232\204\351\207\215\345\277\203.java" @@ -13,17 +13,20 @@ public class 树的重心 { add(a, b); add(b, a); } + vis[1] = 1; dfs(1); System.out.println(ans); } private static int dfs(int u) { - vis[u] = 1; + int size = 0, sum = 0; for (int i = he[u]; i != 0; i = ne[i]) { int j = e[i]; if (vis[j] == 1) continue; + vis[j] = 1; int s = dfs(j); + vis[j] = 0; size = Math.max(size, s); sum += s;//加上孩子节点的个数 } @@ -32,7 +35,7 @@ public class 树的重心 { return sum + 1; } - static int n, cnt, ans=Integer.MAX_VALUE; + static int n, cnt, ans = Integer.MAX_VALUE; static int[] he = new int[100100]; static int[] ne = new int[200100]; static int[] e = new int[200100]; diff --git "a/ACWing/src/dp/\346\240\221\345\275\242dp/\346\240\221\347\232\204\351\207\215\345\277\203.java" "b/ACWing/src/dp/\346\240\221\345\275\242dp/\346\240\221\347\232\204\351\207\215\345\277\203.java" index d3fcd7220e7a79a6bc5b34f09e4f97a38589d354..6fe556c916deb8834d661840678ded91d08f47bc 100644 --- "a/ACWing/src/dp/\346\240\221\345\275\242dp/\346\240\221\347\232\204\351\207\215\345\277\203.java" +++ "b/ACWing/src/dp/\346\240\221\345\275\242dp/\346\240\221\347\232\204\351\207\215\345\277\203.java" @@ -33,7 +33,7 @@ public class 树的重心 { private static int dfs(int u) { vis[u] = true; int size = 0, sum = 1; - //sum为以sum节点为根的子树,节点数量 + //sum为以u节点为根的子树,节点数量 for (int i = he[u]; i != 0; i = ne[i]) { int j = e[i]; if (vis[j]) continue;//不用遍历父节点