提交 8e932a94 编写于 作者: qq_36480062's avatar qq_36480062

c

上级 1e25dd9f
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<node> q = new ArrayDeque<node>();
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());
}
}
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<Integer> q = new ArrayDeque<Integer>();
static int n, m, ans;
}
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<Integer> q = new ArrayDeque<Integer>();
static boolean High = false, low = false;
static int n;
static int[][] g = new int[1010][1010];
static boolean[][] vis = new boolean[1010][1010];
}
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<Integer> q = new ArrayDeque<Integer>();
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;
}
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<node> q = new ArrayDeque<node>();
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];
}
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<Integer> q = new ArrayDeque<Integer>();
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;
}
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<Integer> q = new ArrayDeque<Integer>();
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];
}
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}};
}
......@@ -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];
......
......@@ -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;//不用遍历父节点
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册