提交 9ae067a2 编写于 作者: qq_36480062's avatar qq_36480062

c

上级 5bbf825d
package BFS;
import java.util.LinkedList;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.Scanner;
......@@ -44,7 +44,7 @@ public class 图中点的层次 {
static int[] dis = new int[(int) (1e5 + 10)];
static boolean[] vis = new boolean[(int) (1e5 + 10)];
static int cnt = 1, n, m;
static Queue<Integer> q = new LinkedList<Integer>();
static Queue<Integer> q = new ArrayDeque<Integer>();
static void add(int u, int v) {
e[cnt] = v;
......
......@@ -9,6 +9,7 @@ import java.util.Scanner;
* 如果该联通块没有比当前位置数更小的就是山谷
* 如果该联通块没有比当前位置数更大的就是山峰
* 打上标记,如果都有,则是山坡不计算...
* 遍历的是什么东西,考虑进入队列的是什么东西
*/
public class 山峰和山谷 {
public static void main(String[] args) {
......@@ -53,6 +54,8 @@ public class 山峰和山谷 {
if (g[a][b] > g[x][y]) High = true;
else if (g[a][b] < g[x][y]) low = true;
} else if (!vis[a][b]) {
//显然这一步最重要,进入队列的都是满足未访问过该节点且与拓展之前的节点值相同
//则显然,一遍bfs会把一个连通块权值相同的连通块都遍历到
q.add(a * n + b);
}
}
......
......@@ -2,36 +2,39 @@ package DFS.双向广搜;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
* https://blog.csdn.net/qq_30277239/article/details/104723891
* 双向广搜,显然直接bfs会超时
*/
//@SuppressWarnings("all")
public class 子串变换 {
public static void main(String[] args) {
String A, B;
Scanner sc = new Scanner(System.in);
A = sc.next();
B = sc.next();
int n = 0;
n = 0;
while (sc.hasNext()) {
a[n] = sc.next();
b[n] = sc.next();
aaa[n] = sc.next();
bbb[n] = sc.next();
n++;
}
int step = bfs(A, B);
if (step > 10) System.out.println("No");
else {
System.out.println(step);
}
}
static int n;
static ArrayDeque<String> qa = new ArrayDeque<String>(), qb = new ArrayDeque<String>();
private static int bfs(String a, String b) {
Map<String, Integer> da = new HashMap<String, Integer>();
Map<String, Integer> db = new HashMap<String, Integer>();
HashMap<String, Integer> da = new HashMap<String, Integer>();
HashMap<String, Integer> db = new HashMap<String, Integer>();
qa.add(a);
qb.add(b);
da.put(a, 0);
......@@ -46,14 +49,22 @@ public class 子串变换 {
return 11;
}
private static int extend(ArrayDeque<String> q, Map<String, Integer> da, Map<String, Integer> db, String a, String b) {
private static int extend(ArrayDeque<String> q, HashMap<String, Integer> da, HashMap<String, Integer> db, String a, String b) {
String t = q.poll();
for (int i = 0; i < t.length(); i++) {
for (int i = 0; i < (t != null ? t.length() : 0); i++) {
for (int j = 0; j < n; j++) {
if (!t.substring(i, aaa[j].length()).equals(aaa[j])) continue;
String u = t.substring(0, i) + bbb[j] + t.substring(i + bbb[j].length());
if (db.containsKey(u)) return da.get(t) + 1 + db.get(u);
if (da.containsKey(u)) continue;
da.put(u, da.get(t) + 1);
// if ()
}
}
return 0;
return -1;
}
static int e;
static int N = 6;
static String[] a = new String[N], b = new String[N];
static String[] aaa = new String[N], bbb = new String[N];
}
......@@ -31,6 +31,7 @@ import static java.lang.System.in;
* 3 2 1 0
* 2 1 0 0
* 1 0 0 1
* 找每个点到指定最近的点
* 显然:多源最短路,求每个点到一堆起点的距离,终点不唯一找出最近,可以转化成单源最短路
* 有一个虚拟头结点,与所有起点有一条边权为0的边,
* 体现在bfs中就是队列中添加所有起点!!!
......@@ -52,7 +53,7 @@ public class 矩阵距离 {
m = nextInt();
for (int i = 0; i < n; i++) {
g[i] = next().toCharArray();
g[i] = next().toCharArray();
}
ArrayDeque<node> q = new ArrayDeque<node>();
......@@ -69,21 +70,20 @@ public class 矩阵距离 {
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;
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(dis[i][j] + "");
}
bw.write("\n");
}
bw.flush();
}
static int[][] dir = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
......
package DFS.迭代加深;
import java.util.*;
/**
* https://blog.csdn.net/qq_30277239/article/details/105752519
* 迭代加深,虽然会重复搜,但层数非常深,但使用bfs内存不够,所以使用迭代加深
*/
public class 加成序列 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
path[0] = 1;
while (sc.hasNext()) {
n = sc.nextInt();
if (n == 0) break;
int depth = 1;
while (!dfs(1, depth)) depth++;
for (int i = 0; i < depth; i++) {
System.out.print(path[i] + " ");
}
}
}
static boolean dfs(int u, int depth) {
if (u > depth) return false;
if (path[u - 1] == n) return true;
boolean[] st = new boolean[110];
for (int i = u - 1; i >= 0; i--) {
for (int j = i; j >= 0; j--) {
int s = path[i] + path[j];
if (s > n || s <= path[u - 1] || st[s]) continue;
st[s] = true;
path[u] = s;
if (dfs(u + 1, depth)) return true;
}
}
return false;
}
static int[] path = new int[110];
static int n;
}
###迭代加深
````
dfs会直接走到底,防止走到一个无底洞里面
迭代加深但答案可能会在一个比较浅的位置,给定一个max_depth,(最大层数)
当搜索层数超过max_depth后,就丢弃这个搜索分支,
可以配合A*变成IDA*
一层一层扩大,有点像bfs,
bfs会把一个层数的状态全部放进队列,内存是指数级别
\ No newline at end of file
......@@ -21,7 +21,6 @@ import java.util.Stack;
* ,其中第 i 行的数为编号为 i 的奶牛的高度。
* 输出格式
* 共 N 行,每行输出一个整数,其中第 i 行的输出整数表示编号为 i 的奶牛的最近仰视对象的编号,如果不存在仰视对象,则输出0。
* <p>
* 数据范围
* 1≤N≤105
* 1≤Hi≤106
......@@ -40,7 +39,6 @@ import java.util.Stack;
* 6
* 6
* 0
* <p>
* 我们可以一步步读入奶牛,对于每一头奶牛而言,
* 判断这一头奶牛可以成为哪些奶牛的仰视对象.
* 于是,我们可以将当前奶牛,不断地和栈顶奶牛比较,如果说它身高大于栈顶奶牛,
......
......@@ -2,6 +2,9 @@ package dp.区间dp;
import java.util.Scanner;
/**
*
*/
public class 能量项链 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
......
......@@ -30,7 +30,7 @@ import java.util.Scanner;
* 证明思路:只需要证明任取一点,找到离该点最远距离的点u,点u是直径的一个端点
* 显然,u-v就是树的直径
* 推导过程
* https://blog.csdn.net/qq_30277239/article/details/104396460?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158864856319725247611541%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=158864856319725247611541&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_v2~rank_v25-1
* https://blog.csdn.net/qq_30277239/article/details/104396460
*
*/
public class 树的直径 {
......
......@@ -14,16 +14,16 @@ public class 没有上司的舞会 {
a = sc.nextInt();
b = sc.nextInt();
add(b, a);
hasf[a] = true;
hasFather[a] = true;
}
int root = 1;
while (hasf[root]) root++;
while (hasFather[root]) root++;
dfs(root);
System.out.println(Math.max(f[root][1], f[root][0]));
}
private static void dfs(int u) {
// f[u][1] = happy[u];//选择了u就加上u的幸福指数
// f[u][1] = happy[u];//选择了u就加上u的幸福指数
for (int i = he[u]; i != 0; i = ne[i]) {
int j = e[i];
dfs(j);
......@@ -46,6 +46,6 @@ public class 没有上司的舞会 {
static int[] ne = new int[6010];
static int[] e = new int[6010];
static int[] happy = new int[6010];
static boolean[] hasf = new boolean[6010];
static boolean[] hasFather = new boolean[6010];
}
package dp.线性dp.数字三角形模型;
import java.util.Arrays;
import java.util.Scanner;
/**
......@@ -27,9 +26,6 @@ public class 摘花生 {
while (t-- != 0) {
R = sc.nextInt();
C = sc.nextInt();
for (int i = 0; i < arr.length; i++) {
Arrays.fill(arr[i], 0);
}
for (int i = 1; i <= R; i++) {
for (int j = 1; j <= C; j++) {
arr[i][j] = sc.nextInt();
......
......@@ -4,6 +4,9 @@ import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;
/**
*
*/
public class 紧急情况 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
......
......@@ -3,6 +3,7 @@ package graph.复合单源最短路;
import java.util.Scanner;
/**
* https://www.acwing.com/file_system/file/content/whole/index/content/533831/
* 从a到b,路径的长度定义为第k+1大值
* 二分:
*
......
......@@ -14,7 +14,7 @@ public class 连接格点 {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
for (int i = 0; i <= n * m; i++) {
for (int i = 0; i <= n * m + 10; i++) {
par[i] = i;
}
int a, b, c, d;
......@@ -34,29 +34,28 @@ public class 连接格点 {
int[] dx = {-1, 0, 1, 0};
int[] dy = {0, 1, 0, -1};
int[] dw = {1, 2, 1, 2};
//枚举横向边
//枚举横向边,边权为1
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
for (int u = 0; u < 4; u++) {
a = dx[u] + i;
b = dy[u] + j;
if (a < 1 || a > n || b < 1 || b > m || u % 2 == 1) continue;
if (is(g[a][b], g[i][j])) {
if (!is(g[a][b], g[i][j])) {
res++;
union(g[a][b], g[i][j]);
}
}
}
}
//枚举纵向边
//枚举纵向边,边权为2,满足Kruskal
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
for (int u = 0; u < 4; u++) {
a = dx[u] + i;
b = dy[u] + j;
int w = dw[u];
if (a < 1 || a > n || b < 1 || b > m || u % 2 == 0) continue;
if (is(g[a][b], g[i][j])) {
if (!is(g[a][b], g[i][j])) {
res += 2;
union(g[a][b], g[i][j]);
}
......@@ -66,26 +65,26 @@ public class 连接格点 {
System.out.println(res);
}
private static void getedge() {
int[] dx = {-1, 0, 1, 0};
int[] dy = {0, 1, 0, -1};
int[] dw = {1, 2, 1, 2};
for (int z = 0; z < 2; z++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
for (int u = 0; u < 4; u++) {
if (u % 2 == z) {
int x = i + dx[u], y = j + dy[u], w = dw[u];
if (x != 0 && x <= n && y != 0 && y <= m) {
int a = g[i][j], b = g[x][y];
if (a < b) edge[k++] = new node(a, b, w);
}
}
}
}
}
}
}
// private static void getedge() {
// int[] dx = {-1, 0, 1, 0};
// int[] dy = {0, 1, 0, -1};
// int[] dw = {1, 2, 1, 2};
// for (int z = 0; z < 2; z++) {
// for (int i = 1; i <= n; i++) {
// for (int j = 1; j <= m; j++) {
// for (int u = 0; u < 4; u++) {
// if (u % 2 == z) {
// int x = i + dx[u], y = j + dy[u], w = dw[u];
// if (x != 0 && x <= n && y != 0 && y <= m) {
// int a = g[i][j], b = g[x][y];
// if (a < b) edge[k++] = new node(a, b, w);
// }
// }
// }
// }
// }
// }
// }
static class node {
int x, y, w;
......@@ -109,11 +108,8 @@ public class 连接格点 {
}
static int find(int x) {
while (x != par[x]) {
par[x] = par[par[x]];
x = par[x];
}
return x;
if (x == par[x]) return x;
return par[x] = find(par[x]);
}
static void union(int x, int y) {
......
......@@ -17,7 +17,6 @@ import java.util.Scanner;
* 5
* 输出样例:
* 2
* <p>
* 类似快速幂:
* a*b转换成加法
* a+a+a 加法操作b次
......
package 递归;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import static java.lang.System.in;
......@@ -28,12 +27,21 @@ import static java.lang.System.in;
* 3 2 1
* 排列型枚举,n个数,有n个坑,第一个坑有n种选择,第二个坑有n-1中选择,第n个坑只有一种选择
* 第一个坑的n种选择,是平行的,
* 交换性枚举每一位,是效率最高的
*/
public class 排列枚举 {
public static void main(String[] args) {
Scanner sc = new Scanner(in);
n = sc.nextInt();
long s = System.nanoTime();
d(0, 0);
long t = System.nanoTime();
System.out.println((t - s) / 1e8);
s = System.nanoTime();
dfs(0, 0);
t = System.nanoTime();
System.out.println((t - s) / 1e8);
}
static int n = 3;
......@@ -42,25 +50,26 @@ public class 排列枚举 {
//u代表结果path有多少个
static void dfs(int u, int state) {//state通过位运算作为vis数字,
if (u == n) {
for (Integer w : path) {
System.out.print(w + " ");
}
System.out.println();
// for (Integer w : path) {
// System.out.print(w + " ");
// }
// System.out.println();
return;
}
for (int i = 0; i < n; i++) {//枚举n种平行选择
if (!(((state >> i) & 1) == 1)) {//如果这个数字没被选,就选
path.add(i + 1);
for (int i = 0; i < n; i++) {//每一位枚举n种平行选择
if (((state >> i) & 1) != 1) {//如果这个数字没被选,就选
path.add(arr[i]);
dfs(u + 1, state | (1 << i));//选上
path.remove(path.size() - 1);//恢复状态
}
}
}
static int[] arr = {4, 3, 5, 2};
static int[] arr = {4, 3, 5, 2, 3, 4, 1, 4, 5, 1, 2};
static void d(int u, int k) {
if (u == n) {
System.out.println(Arrays.toString(arr));
// System.out.println(Arrays.toString(arr));
return;
}
for (int i = k; i < n; i++) {
......
......@@ -33,27 +33,32 @@ public class 组合m个数 {
// n = sc.nextInt();
// m = sc.nextInt();
long l = System.nanoTime();
dfs(0, 0, 0);
long e = System.nanoTime();
System.out.println(e - l);
System.out.println((e - l) / 1e9);
l = System.nanoTime();
dfs(0, 0);
e = System.nanoTime();
System.out.println((e - l) / 1e9);
}
static int m = 2, n = 6;
static int[] arr = {23, 1, 2, 4, 7, 3};
static int[] vis = new int[6];
static int m = 3, n = 12;
static int[] arr = {23, 1, 2, 4, 7, 3, 6, 8, 1, 5, 12,13};
static int[] vis = new int[12];
//枚举到第u位 ,sum是当前选了几个,state是vis数组
static void dfs(int u, int sum, int state) {
if (sum + (n - u) < m) return;//就是n-u就是剩余还没有选的数字的数量,
// sum+(n-u)<m就是剩余的数字都选上,也不够m个数字,所以剪枝
if (sum == m) {//选了m个就输出
for (int i = 0; i < n; i++) {
if ((state >> i & 1) == 1) {
System.out.print(i + 1 + " ");
}
}
System.out.println();
// for (int i = 0; i < n; i++) {
// if ((state >> i & 1) == 1) {
// System.out.print(arr[i] + " ");
// }
// }
// System.out.println();
return;
}
if (u == n) return;//所有数字都选完了
......@@ -66,11 +71,11 @@ public class 组合m个数 {
static void dfs(int u, int k) {
if (k + n - u < m) return;
if (k == m) {
for (int i = 0; i < n; i++) {
if (vis[i] == 1)
System.out.print(arr[i] + " ");
}
System.out.println();
// for (int i = 0; i < n; i++) {
// if (vis[i] == 1)
// System.out.print(arr[i] + " ");
// }
// System.out.println();
return;
}
if (u == n) return;//n个数据都用完了
......
......@@ -27,11 +27,12 @@ public class 随机选数 {
public static void main(String[] args) {
// Scanner sc = new Scanner(in);
// n = sc.nextInt();
dfs(0);
dfs(0, 0);
//dfs(0, 0);
}
static int n = 3;
static int[] arr = {2, 4, 3};
static int[] arr = {1, 2, 3};
static int[] vis = new int[10];
//dfs求子集,选和不选
......@@ -52,4 +53,18 @@ public class 随机选数 {
dfs(u + 1);//用第u个数字,把state的第u位变成为1
vis[u] = 0;
}
static void dfs(int u, int state) {
if (u == n) {
if (state==0)return;
for (int i = 0; i < n; i++) {
if (((state >> i) & 1) == 1)
System.out.print(arr[i] + " ");
}
System.out.println();
return;
}
dfs(u + 1, state);
dfs(u + 1, state | (1 << u));
}
}
\ No newline at end of file
......@@ -28,28 +28,28 @@ public class 最小路径和 {
* 该递推方程代表,走到(i,j)的值,应当是(i-1,j)和(i,j-1)之间的较小值,
* 再加上该位置的值,就是到(i,j)的最小路径和
*
* @param arr 该数组
* @param grid 该数组
* @return 最小路径和
*/
public static int zq(int[][] arr) {
if (arr.length == 0 || arr[0].length == 0) return 0;
public static int zq(int[][] grid) {
if (grid.length == 0 || grid[0].length == 0) return 0;
//首先判断数组是不是为空
int m = arr.length, n = arr[0].length;
int m = grid.length, n = grid[0].length;
int[][] dp = new int[m][n];
{//基础条件代码块
dp[0][0] = arr[0][0];
dp[0][0] = grid[0][0];
for (int i = 1; i < m; i++) {
dp[i][0] = arr[i][0] + dp[i - 1][0];
dp[i][0] = grid[i][0] + dp[i - 1][0];
}//初始化第一列
for (int i = 1; i < n; i++) {
dp[0][i] = arr[0][i] + dp[0][i - 1];
dp[0][i] = grid[0][i] + dp[0][i - 1];
}//初始化第一行
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + arr[i][j];
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
}
}
return dp[m - 1][n - 1];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册