提交 35ce1371 编写于 作者: qq_36480062's avatar qq_36480062

c

上级 8e932a94
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
*/
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;
while (sc.hasNext()) {
a[n] = sc.next();
b[n] = sc.next();
n++;
}
int step = bfs(A, B);
if (step > 10) System.out.println("No");
else {
}
}
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>();
qa.add(a);
qb.add(b);
da.put(a, 0);
db.put(b, 0);
while (!qa.isEmpty() && !qb.isEmpty()) {
int t = 0;
if (qa.size() <= qb.size()) {
t = extend(qa, da, db, a, b);
} else t = extend(qb, da, db, b, a);
if (t <= 10) return t;
}
return 11;
}
private static int extend(ArrayDeque<String> q, Map<String, Integer> da, Map<String, Integer> db, String a, String b) {
String t = q.poll();
for (int i = 0; i < t.length(); i++) {
}
return 0;
}
static int N = 6;
static String[] a = new String[N], b = new String[N];
}
package DFS.双端队列;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Scanner;
/**
* 超级复杂...
* https://blog.csdn.net/qq_30277239/article/details/104719098
* 当一个图的边权只可能是0或者1时,就可以使用双端队列BFS求解
* 本题求从左上角到右下角要想连通的最小旋转次数,
* 一个方格的对角线之间,如果有连线,就可以被视为这两点之间的边权长度是0,
* 如果需要旋转才有连线,则视边权的长度为1,
* 所以本题就转化为了一个边权只有01两种情况的最短路问题。
* 为什么BFS可以解决边权不等的最短路问题,
* 可以说是此时BFS的队列相当于dijkstra算法中的优先级队列,
* 是单调的,也是由BFS队列中元素的两段性和单调性决定的。
* dijkstra算法在非负权图都是正确的,但需要建图
* 经典做法,双端队列
* 使用方法:拓展的节点,边权为0插入队头,边权为1插入队尾,取只取队头
* 转化为Dijkstra算法,把问题转化为Dijkstra算法能解决的问题
* 队列前面的元素一定小于等于后面的元素到达源点的距离
* bfs中队列具有两段性,单调性,
* 以上双端队列的方式仍然具有两段性,和单调性
* 则正确
* 有边权为0/1的边,有可能每条边加入队列多次
* 比如di=dj di+1>dj+0
* 队列后面的边权可能更小
* 由于只能走对角线,每个点的横纵坐标都会变1
* 奇点就是横纵坐标是奇数的点,同理偶点
* 则要求终点是偶点
* 起点和终点奇偶性相同才可以到达
* 起点(0,0)自然是偶点
*/
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);
int t = sc.nextInt();
while (t-- != 0) {
n = sc.nextInt();
m = sc.nextInt();
for (int i = 0; i < n; i++) {
g[i] = sc.next().toCharArray();
}
if (((n + m) & 1) == 1) System.out.println("NO SOLUTION");
else {
bfs(0, 0);
System.out.println(dist[n][m]);
}
}
}
private static int bfs(int x, int y) {
q.clear();
int t = Integer.MAX_VALUE / 2;
for (int i = 0; i < dist.length; i++) {
Arrays.fill(dist[i], t);
}
for (int i = 0; i < vis.length; i++) {
Arrays.fill(vis[i], false);
}
q.add(new node(x, y));
dist[x][y] = 0;
while (!q.isEmpty()) {
node e = q.poll();
if (vis[e.x][e.y]) continue;
vis[e.x][e.y] = true;
for (int i = 0; i < 4; i++) {
int nx = e.x + dir[i][0], ny = e.y + dir[i][1];
if (nx < 0 || nx > n || ny < 0 || ny > m) continue;
int ex = e.x + idx[i][0], ey = e.y + idx[i][1];
int d = dist[e.x][e.y] + (g[ex][ey] != op.charAt(i) ? 1 : 0);
if (d < dist[nx][ny]) {
dist[nx][ny] = d;
if (g[ex][ey] == op.charAt(i)) q.addFirst(new node(nx, ny));
else q.addLast(new node(nx, ny));
}
}
}
return 0;
}
static String op = "\\/\\/";
static int[][] dir = {{-1, -1}, {-1, 1}, {1, 1}, {1, -1}};
static int[][] idx = {{-1, -1}, {-1, 0}, {0, 0}, {0, -1}};
static ArrayDeque<node> q = new ArrayDeque<node>();
static int n, m, N = 510, M = N * N;
static int[][] dist = new int[N][N];
static char[][] g = new char[N][N];
static boolean[][] vis = new boolean[N][N];
}
package DFS.启发式搜索;
import java.util.Scanner;
/**
*
*/
public class 八数码 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String start, seq;
StringBuilder s = new StringBuilder();
for (int i = 0; i < 8; i++) {
s.append(sc.nextLine());
}
start = s.toString().replace(" ", "");
System.out.println(start);
}
}
package BFS;
package DFS.多源bfs;
import java.io.*;
import java.util.ArrayDeque;
......@@ -31,6 +31,10 @@ import static java.lang.System.in;
* 3 2 1 0
* 2 1 0 0
* 1 0 0 1
* 显然:多源最短路,求每个点到一堆起点的距离,终点不唯一找出最近,可以转化成单源最短路
* 有一个虚拟头结点,与所有起点有一条边权为0的边,
* 体现在bfs中就是队列中添加所有起点!!!
* 体现在dijkstra就是要真的把那个源点建立出来
*/
public class 矩阵距离 {
static class node {
......
package DFS.搜索顺序;
import java.util.Scanner;
/**
* https://blog.csdn.net/qq_30277239/article/details/104799213
* 6
* 14 20 33 117 143 175
*/
public class 分成互质组 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
dfs(1, 0, 0, 0);
System.out.println(ans);
}
static boolean check(int[] g, int gc, int i) {
for (int j = 0; j < gc; j++) {
if (gcd(a[g[j]], a[i]) > 1) return false;
}
return true;
}
//g代表当前哪一组,gc代表枚举到组内第几个元素tc表示当前一共处理多少数,start代表组内从哪个数开始枚举
static void dfs(int g, int gc, int tc, int start) {
if (g >= ans) return;
if (tc == n) {
ans = g;
}
boolean f = true;
for (int i = start; i < n; i++) {
if (!vis[i] && check(group[g], gc, i)) {
vis[i] = true;
group[g][gc] = i;
dfs(g, gc + 1, tc + 1, i + 1);
vis[i] = false;
f = false;
}
}
if (f) dfs(g + 1, 0, tc, 0);
}
static int n, ans = 10;
static int[] a = new int[10];
static int[][] group = new int[10][10];
static boolean[] vis = new boolean[10];
static int gcd(int a, int b) {
if (b == 0) return a;
return gcd(b, a % b);
}
}
package DFS.搜索顺序;
import java.util.Scanner;
/**
*https://blog.csdn.net/qq_30277239/article/details/104782198
*/
public class 单词接龙 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
for (int i = 0; i < n; i++) {
word[i] = sc.next();
}
char start = sc.next().charAt(0);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
String a = word[i], b = word[j];
for (int k = 1; k < Math.min(a.length(), b.length()); k++) {
if (a.substring(a.length() - k, k).equals(b.substring(0, k))) {
//a的后缀,和b的前缀匹配
g[i][j] = k;
break;
}
}
}
}
for (int i = 0; i < n; i++) {
if (word[i].charAt(0) == start) {
dfs(word[i], i);
}
}
}
static void dfs(String s, int last) {
ans = Math.max(s.length(), ans);
vis[last]++;
for (int i = 0; i < n; i++) {
if (g[last][i] != 0 && vis[i] < 2) {
dfs(s + word[i].substring(g[last][i]), i);
}
}
}
static int n, N = 21, ans;
static String[] word = new String[N];
static int[] vis = new int[N];
static int[][] g = new int[N][N];
}
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/104701375
* 八数码同类题
* 有向图最短步数模型,要把状态存下来
* 用hash法存状态,或者康托展开
* 最小字典序,在拓展每个状态的时候,先A,B,C
* 显然bfs一定是最短路,假设最后一步,走A和B都能达到最短路,
* 则走到A就结束搜索,满足字典序,
* 则显然同理可证,多条最短路中第一个字典序最小
* 因为先拓展的状态,先放进队列.
* 2 6 8 4 5 7 3 1
* 7
* B C A B C C B
*/
public class 魔板 {
static class node {
char x;
String s;
public node(char x, String s) {
this.x = x;
this.s = s;
}
}
public static void main(String[] args) {
StringBuilder start = new StringBuilder(), end = new StringBuilder();
Scanner s = new Scanner(System.in);
for (int i = 0; i < 8; i++) {
end.append(s.nextInt());
}
for (int i = 0; i < 8; i++) {
start.append(i + 1);
}
String st = start.toString();
String ed = end.toString();
bfs(st, ed);
if (st.equals(ed)) System.out.println(0);
else {
System.out.println(dist.get(ed));
StringBuilder res = new StringBuilder();
while (!ed.equals(st)) {
res.append(pre.get(ed).x);
ed = pre.get(ed).s;
}
res.reverse();
for (int i = 0; i < res.length(); i++) {
System.out.print(res.charAt(i) + " ");
}
}
}
private static void bfs(String start, String end) {
if (start.equals(end)) return;
q.add(start);
dist.put(start, 0);
while (!q.isEmpty()) {
String t = q.poll();
String[] tem = new String[3];
tem[0] = move0(t);
tem[1] = move1(t);
tem[2] = move2(t);
for (int i = 0; i < 3; i++) {
String m = tem[i];
if (!dist.containsKey(m)) {
dist.put(m, dist.get(t) + 1);
pre.put(m, new node((char) (i + 'A'), t));
if (m.equals(end)) return;
q.add(m);
}
}
}
}
static int[][] g = new int[2][4];
static void set(String s) {
for (int i = 0; i < 4; i++) {
g[0][i] = s.charAt(i) - '0';
}
for (int i = 3, j = 4; i >= 0; i--, j++) {
g[1][i] = s.charAt(j) - '0';
}
}
static String get() {
StringBuilder res = new StringBuilder();
for (int i = 0; i < 4; i++) {
res.append(g[0][i]);
}
for (int i = 3; i >= 0; i--) {
res.append(g[1][i]);
}
return res.toString();
}
private static String move2(String t) {
set(t);
int a = g[0][1];
g[0][1] = g[1][1];
g[1][1] = g[1][2];
g[1][2] = g[0][2];
g[0][2] = a;
return get();
}
private static String move1(String t) {
set(t);
int v0 = g[0][3], v1 = g[1][3];
for (int i = 3; i > 0; i--) {
for (int j = 0; j < 2; j++) {
g[j][i] = g[j][i - 1];
}
}
g[0][0] = v0;
g[1][0] = v1;
return get();
}
private static String move0(String t) {
set(t);
for (int i = 0; i < 4; i++) {
int e = g[0][i];
g[0][i] = g[1][i];
g[1][i] = e;
}
return get();
}
static Map<String, Integer> dist = new HashMap<String, Integer>();
static Map<String, node> pre = new HashMap<String, node>();
static ArrayDeque<String> q = new ArrayDeque<String>();
}
......@@ -4,8 +4,10 @@ import java.util.Arrays;
import java.util.Scanner;
/**
* https://blog.csdn.net/qq_30277239/article/details/104780078
* 1
* 5 4 0 0
* 有多少种方式走满整个棋盘
*/
public class 马走日 {
public static void main(String[] args) {
......@@ -31,7 +33,6 @@ public class 马走日 {
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;
......
import java.io.*;
import java.util.ArrayDeque;
import java.util.LinkedList;
import java.util.StringTokenizer;
import static java.lang.System.in;
public class IO加速 {
public static void main(String[] args) throws IOException {
tokenizer=new StringTokenizer("123123 15412 4312412");
System.out.println(tokenizer.nextToken());
System.out.println(tokenizer.nextToken());
System.out.println(tokenizer.hasMoreTokens());
System.out.println(tokenizer.nextToken());
System.out.println(tokenizer.hasMoreTokens());
static void f() {
long s = System.nanoTime();
LinkedList<Integer> l = new LinkedList<Integer>();
for (int i = 0; i < 3000000; i++) {
l.add(i);
}
for (int i = 0; i < 3000000; i++) {
l.poll();
}
long t = System.nanoTime();
System.out.println((t - s) / 1e8);
s = System.nanoTime();
ArrayDeque<Integer> r = new ArrayDeque<Integer>();
for (int i = 0; i < 3000000; i++) {
r.addFirst(i);
}
for (int i = 0; i < 3000000; i++) {
if ((i & 1) == 1) r.pollLast();
else r.pollFirst();
}
t = System.nanoTime();
System.out.println((t - s) / 1e8);
}
//标准输出流,只能输出字符串,不能输出数字!!!
bw.write(1 + " ");
bw.flush();
public static void main(String[] args) throws IOException {
f();
// tokenizer = new StringTokenizer("123123 15412 4312412");
// System.out.println(tokenizer.nextToken());
// System.out.println(tokenizer.nextToken());
// System.out.println(tokenizer.hasMoreTokens());
//
// System.out.println(tokenizer.nextToken());
//
// System.out.println(tokenizer.hasMoreTokens());
//
//
// //标准输出流,只能输出字符串,不能输出数字!!!
// bw.write(1 + " ");
// bw.flush();
}
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
......
......@@ -18,6 +18,14 @@ public class 能量项链 {
}
}
}
for (int len = 1; len <= n + 1; len++) {
for (int l = 1; l + len - 1 <= n * 2; l++) {
int r = l + len - 1;
for (int k = l; k < r; k++) {
}
}
}
int res = 0;
for (int i = 1; i <= n; i++) {
res = Math.max(res, f[i][i + n]);
......
package dp.数位dp;
import java.util.ArrayList;
import java.util.Scanner;
/**
* 数位dp的技巧
* 489199 894799999 15 3
* 15 20 2 2
*/
public class 度的数量 {
public static void main(String[] args) {
init();
Scanner sc = new Scanner(System.in);
l = sc.nextInt();
r = sc.nextInt();
K = sc.nextInt();
B = sc.nextInt();
System.out.println(dp(r) - dp(l - 1));
}
//求出从0~n中求出满足要求的数
static int dp(int n) {
if (n == 0) return 0;
ArrayList<Integer> num = new ArrayList<Integer>();
//把数字转换成B进制
while (n != 0) {
num.add(n % B);
n /= B;
}
System.out.println(num);
int res = 0, last = 0;
for (int i = num.size() - 1; i >= 0; i--) {
int x = num.get(i);
if (x != 0) {
res += f[i][K - last];
if (x > 1) {
if (K - last - 1 >= 0) res += f[i][K - last - 1];
break;
}else {
last++;
if (last > K) break;
}
}
if (i == 0 && last == K) res++;
}
return res;
}
/**
* 求组合数
* 状态定义:f[i,j]前i个数可选,选j个有多少种组合方案
* 状态划分2个:j个数已经选完,那么f[i-1][j]
* j个数选的是第i个元素,f[i-1][j-1]
*/
static void init() {
for (int i = 0; i < N; i++) {
for (int j = 0; j <= i; j++) {
if (j == 0) f[i][j] = 1;
else f[i][j] = f[i - 1][j] + f[i - 1][j - 1];
}
}
}
static int l, r, K, B, N = 35;
static int[][] f = new int[N][N];
}
......@@ -10,5 +10,3 @@
技巧2:
使用树的角度来考虑
......@@ -37,6 +37,11 @@ package dp.数位dp;
* 196 512 186 104 87 93 97 97 142 196
* 398 1375 398 398 405 499 499 495 488 471
* 294 1256 296 296 296 296 287 286 286 247
* <p>
* 本题要统计a~b之间0到9出现的次数,暴力枚举需要O(n)的时间,
* 寻找其中的规律可大幅提高效率。设count(n,x)可以统计1到n中x出现的次数,
* 则a到b中x出现的次数大于count(b) - count(a - 1)。
* 下面要解决的问题就是如何求1到n中x出现的次数。
*/
public class 计数问题 {
public static void main(String[] args) {
......
......@@ -29,7 +29,8 @@ import static java.lang.Math.min;
* 18
* 状压dp
* 该图是完全图
*
* 2的整数次幂-1的二进制位全是1111111
* f[i,j]状态表示为从0走到顶点j状态为i的所有走法
*/
public class 哈密尔顿回路 {
public static void main(String[] args) {
......@@ -44,12 +45,14 @@ public class 哈密尔顿回路 {
Arrays.fill(f[i], 0x3f3f3f3f);
}
f[1][0] = 0;
for (int i = 1; i < 1 << n; i++) {
if ((i & 1) == 0) continue;
for (int j = 0; j < n; j++) {
if (((i >> j) & 1) == 1) {
for (int i = 1; i < 1 << n; i++) {//二进制枚举
if ((i & 1) == 0) continue;//路径必然包含起点,最后一位必须为1,快一倍
for (int j = 0; j < n; j++) {//取出每一位
if (((i >> j) & 1) == 1) {//取出每一位
int t = i - (1 << j);
//把第j位置为0
int s = t - 1 != 0 ? 1 : 0;
//如果只剩下了起点和终点,才需要枚举以k = 0的情况
for (int k = s; k < n; k++) {
if ((t >> k & 1) == 1) {
f[i][j] = min(f[i][j], f[t][k] + g[k][j]);
......@@ -59,6 +62,8 @@ public class 哈密尔顿回路 {
}
}
System.out.println(f[(1 << n) - 1][n - 1]);
//从0走到j路径为1111111的最短路径,也就是经过所有点到达n-1这个点
}
static int N = 20, M = 1 << 20, n;
......
package graph.单源最短路;
import java.util.Arrays;
import java.util.Scanner;
/**
* https://blog.csdn.net/chrisblogtk/article/details/51099957?utm_source=blogxgwz7
* 对于每个点的时间等于他到指挥部的最短距离
* 1号点是指挥部
* 如果有点无法到达输出-1
* 然后最短距离的最大值为最大
* 4 4
* 1 2 4
* 2 3 7
* 2 4 1
* 3 4 6
* out:
* 11
*/
public class 信使 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
int a, b, c;
for (int i = 0; i < 110; i++) {
Arrays.fill(g[i], Integer.MAX_VALUE / 3);
}
for (int i = 0; i < m; i++) {
a = sc.nextInt();
b = sc.nextInt();
c = sc.nextInt();
g[a][b] = g[b][a] = Math.min(g[a][b], c);
}
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
g[i][j] = Math.min(g[i][j], g[i][k] + g[k][j]);
}
}
}
int res = 0;
for (int i = 1; i <= n; i++) {
if (g[1][i] == Integer.MAX_VALUE / 2) {
res = -1;
break;
} else res = Math.max(res, g[1][i]);
}
System.out.println(res);
}
static int[][] g = new int[110][110];
static int n, m;
}
package graph.单源最短路;
import java.util.Arrays;
import java.util.Scanner;
/**
* https://blog.csdn.net/a1097304791/article/details/88971315
* POJ - 1062
* 每一种购买方式
* 都可以对应虚拟源点到到达终点的一条路径
* 寻找最短路
* 等级问题的话,枚举等级区间
*/
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 < w.length; i++) {
Arrays.fill(w[i], Integer.MAX_VALUE / 2);
w[i][i] = 0;
}
int price, cnt;
for (int i = 1; i <= n; i++) {
price = sc.nextInt();
level[i] = sc.nextInt();
cnt = sc.nextInt();
w[0][i] = Math.min(price, w[0][i]);
while (cnt-- != 0) {
int id, cost;
id = sc.nextInt();
cost = sc.nextInt();
w[id][i] = Math.min(w[id][i], cost);
}
}
int res = Integer.MAX_VALUE / 2;
for (int i = level[1] - m; i <= level[1]; i++) {
res = Math.min(res, dijkstra(i, i + m));
}
System.out.println(res);
}
static int dijkstra(int down, int up) {
Arrays.fill(dist, 0x3f3f3f3f);
Arrays.fill(vis, false);
dist[0] = 0;
for (int i = 1; i <= n; i++) {
int t = -1;
for (int j = 0; j <= n; j++) {
if (!vis[j] && (t == -1 || dist[t] > dist[j])) t = j;
}
vis[t] = true;
for (int j = 1; j <= n; j++) {
if (level[j] >= down && level[j] <= up) {
dist[j] = Math.min(dist[j], dist[t] + w[t][j]);
}
}
}
return dist[1];
}
static int[][] w = new int[110][110];
static int[] level = new int[110];
static int[] dist = new int[110];
static boolean[] vis = new boolean[110];
static int n, m;
}
package graph.单源最短路;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Scanner;
/**
* https://blog.csdn.net/SWEENEY_HE/article/details/81413683
* 2
* 5
* 1 4
* 2 3 4 5
* out
* 1
* 样例输出
* 3 7
* 6 7
* 4 7 3 6
* 2 1 3 5
* out
* 2
* 建图,问题,
* 2 3 4 5可以看做2-3 2-4 2-5 3-4 3-5 4-5
* 显然:2可以直接到3,2也可以直接到4,2也可以直接到5
* 边权都为1可以使用bfs做
* 则显然求最小换乘次数,转换成求最短路径问题
*/
public class 最优乘车 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
m = sc.nextInt();
n = sc.nextInt();
sc.nextLine();//换行
int[] stop = new int[510];
for (int t = 0; t < m; t++) {
String[] s2 = sc.nextLine().split(" ");
for (int i = 0; i < s2.length; i++) {
stop[i] = Integer.parseInt(s2[i]);
}
for (int i = 0; i < s2.length - 1; i++)
for (int j = i + 1; j < s2.length; j++)
g[stop[i]][stop[j]] = 1;
}
bfs();
if (dist[n] == Integer.MAX_VALUE / 2) System.out.println("NO");
else
System.out.println(Math.max(dist[n] - 1, 0));
}
static int[][] g = new int[510][510];
static int[] dist = new int[510];
static int n, m;
static void bfs() {
Arrays.fill(dist, Integer.MAX_VALUE / 2);
ArrayDeque<Integer> q = new ArrayDeque<Integer>();
q.add(1);
dist[1] = 0;
while (!q.isEmpty()) {
int t = q.poll();
for (int i = 1; i <= n; i++) {
if (g[t][i] == 1 && dist[i] > dist[t] + 1) {
dist[i] = dist[t] + 1;
q.add(i);
}
}
}
}
}
package graph.单源最短路;
import java.util.PriorityQueue;
import java.util.Scanner;
/**
* https://blog.csdn.net/LTH060226/article/details/86535023
* n个人,某些人的银行账号可以相互转账
* 这些人的转账手续费各不相同
* 给定这些人转账时需要从转账金额里扣除百分之几的手续费,请问A最少需要多少钱使得转账后B收到100元。
* 输出A使得B到账100元最少需要的总费用。精确到小数点后8位。
* Sample Input
* 3 3
* 1 2 1
* 2 3 2
* 1 3 3
* 1 3
* Sample Output
* 103.07153164
*/
public class 最小花费 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
int a, b, c;
for (int i = 0; i < m; i++) {
a = sc.nextInt();
b = sc.nextInt();
c = sc.nextInt();
add(a, b, 1.0 - c / 100.0);
add(b, a, 1.0 - c / 100.0);
}
s = sc.nextInt();
end = sc.nextInt();
System.out.printf("%.8f", 100.0 / dijkstra(s));
}
static class node implements Comparable<node> {
double x;
int y;
public node(double x, int y) {
this.x = x;
this.y = y;
}
@Override
public int compareTo(node node) {
return (int) (x * 1000 - node.x * 10000);
}
}
static double dijkstra(int s) {
PriorityQueue<node> q = new PriorityQueue<node>();
q.add(new node(1, s));
dis[s] = 1;
while (!q.isEmpty()) {
node p = q.poll();
int t = p.y;
if (vis[t]) continue;
vis[t] = true;
for (int i = he[t]; i != 0; i = ne[i]) {
if (dis[e[i]] < dis[t] * w[i]) {
dis[e[i]] = dis[t] * w[i];
q.add(new node(w[i], e[i]));
}
}
}
return dis[end];
}
static void add(int a, int b, double c) {
e[cnt] = b;
w[cnt] = c;
ne[cnt] = he[a];
he[a] = cnt++;
}
static int[] he = new int[2550];
static int[] ne = new int[6550 * 2];
static int[] e = new int[6550 * 2];
static double[] w = new double[6550 * 2];
static boolean[] vis = new boolean[2560];
static double[] dis = new double[2560];
static int n, m, cnt = 1, s, end;
}
package graph.单源最短路;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;
/**
* http://blog.sina.com.cn/s/blog_83ac6af80102v0zj.html
* 裸最短路
*/
public class 热浪 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
s = sc.nextInt();
t = sc.nextInt();
int a, b, c;
for (int i = 0; i < m; i++) {
a = sc.nextInt();
b = sc.nextInt();
c = sc.nextInt();
add(a, b, c);
add(b, a, c);
}
dijkstra();
System.out.println(dis[t]);
}
static void spfa() {
Arrays.fill(dis, Integer.MAX_VALUE - 124124);
q.add(s);
dis[s] = 0;
vis[s] = true;
while (!q.isEmpty()) {
int p = q.pop();
vis[p] = false;
for (int i = he[p]; i != 0; i = ne[i]) {
if (dis[e[i]] > dis[p] + w[i]) {
dis[e[i]] = dis[p] + w[i];
if (!vis[e[i]]) {
vis[e[i]] = true;
if (!q.isEmpty() && dis[e[i]] < dis[q.peekFirst()]) q.addFirst(e[i]);
else q.add(e[i]);
}
}
}
}
}
static class node implements Comparable<node> {
int x, y;
public node(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public int compareTo(node node) {
return x - node.x;
}
}
static void dijkstra() {
PriorityQueue<node> q = new PriorityQueue<node>();
Arrays.fill(dis, Integer.MAX_VALUE / 2);
dis[s] = 0;
q.add(new node(0, s));
while (!q.isEmpty()) {
node ed = q.poll();
int y = ed.y;
if (vis[y]) continue;
vis[y] = true;
for (int i = he[y]; i != 0; i = ne[i]) {
if (dis[e[i]] > dis[y] + w[i]) {
dis[e[i]] = dis[y] + w[i];
q.add(new node(w[i], e[i]));
}
}
}
}
static void add(int a, int b, int c) {
e[cnt] = b;
w[cnt] = c;
ne[cnt] = he[a];
he[a] = cnt++;
}
static int[] he = new int[2550];
static int[] ne = new int[6550 * 2];
static int[] e = new int[6550 * 2];
static int[] w = new int[6550 * 2];
static boolean[] vis = new boolean[2560];
static int[] dis = new int[2560];
static ArrayDeque<Integer> q = new ArrayDeque<Integer>();
static int n, m, s, t, cnt = 1;
}
package graph.单源最短路;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Scanner;
/**
* https://www.cnblogs.com/zqzxwdm/p/5590204.html
* 3 4 5
* 2
* 3
* 4
* 1 2 1
* 1 3 5
* 2 3 7
* 2 4 3
* 3 4 5
* 选一个节点作为起点使得其他节点到该节点的所有步数最少,显然
* 多源汇最短路,n为500 Floyd O(n^3)超时
* 使用spfa
* O(nm)最差O(n^2m)
* 或者使用Dijkstra
* O(nm log n)
*/
public class 香甜的黄油 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
p = sc.nextInt();
m = sc.nextInt();
for (int i = 0; i < n; i++) {
id[i] = sc.nextInt();
}
int a, b, c;
for (int i = 0; i < m; i++) {
a = sc.nextInt();
b = sc.nextInt();
c = sc.nextInt();
add(a, b, c);
add(b, a, c);
}
for (int i = 1; i <= p; i++) {
ans = Math.min(ans, spfa(i));
}
System.out.println(ans);
}
static int spfa(int s) {
int res = 0;
Arrays.fill(dis, Integer.MAX_VALUE / 2);
dis[s] = 0;
q.add(s);
vis[s] = true;
while (!q.isEmpty()) {
int p = q.poll();
vis[p] = false;
for (int i = he[p]; i != 0; i = ne[i]) {
if (dis[e[i]] > dis[p] + w[i]) {
dis[e[i]] = dis[p] + w[i];
if (!vis[e[i]]) {
vis[e[i]] = true;
if (!q.isEmpty() && dis[e[i]] < dis[q.peekFirst()]) q.addFirst(e[i]);
else q.add(e[i]);
}
}
}
}
for (int i = 0; i < n; i++) {
int j = id[i];
if (dis[j] == Integer.MAX_VALUE / 2) return Integer.MAX_VALUE / 2;
res += dis[j];
}
return res;
}
static int ans = Integer.MAX_VALUE;
static void add(int a, int b, int c) {
e[cnt] = b;
w[cnt] = c;
ne[cnt] = he[a];
he[a] = cnt++;
}
static int[] he = new int[2550];
static int[] ne = new int[6550 * 2];
static int[] e = new int[6550 * 2];
static int[] w = new int[6550 * 2];
static boolean[] vis = new boolean[2560];
static int[] dis = new int[2560];
static ArrayDeque<Integer> q = new ArrayDeque<Integer>();
static int n, m, p, cnt = 1;
static int[] id = new int[2523];
}
package graph.复合单源最短路;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Scanner;
/**
* https://blog.csdn.net/qq_43256272/article/details/103392889
* 使用spfa+dfs
* 复杂度 6*O(m)+5!
* 5!只有120不需要剪枝
*/
public class 新年好 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
source[0] = 1;
for (int i = 1; i <= 5; i++) {
source[i] = sc.nextInt();//起点
}
int a, b, c;
while (m-- != 0) {
a = sc.nextInt();
b = sc.nextInt();
c = sc.nextInt();
add(a, b, c);
add(b, a, c);
}
for (int i = 0; i < 6; i++) {
spfa(source[i], dis[i]);
}
System.out.println(dfs(1, 0, 0));
}
static int dfs(int u, int start, int dist) {
if (u == 6) return dist;
int res = Integer.MAX_VALUE / 2;
for (int i = 1; i <= 5; i++) {
if (!vis[i]) {
int next = source[i];
vis[i] = true;
res = Math.min(res, dfs(u + 1, i, dist + dis[start][next]));
vis[i] = false;
}
}
return res;
}
//起点是s,把单源最短路放进dis[i]
private static void spfa(int s, int[] dis) {
q.add(s);
Arrays.fill(dis, Integer.MAX_VALUE / 2);
Arrays.fill(vis,false);
dis[s] = 0;
while (!q.isEmpty()) {
int t = q.poll();
vis[t] = false;
for (int i = he[t]; i != 0; i = ne[i]) {
int j = e[i];
if (dis[j] > dis[t] + w[i]) {
dis[j] = dis[t] + w[i];
if (!vis[j]) {
vis[j] = true;
if (!q.isEmpty() && dis[j] < dis[q.peekFirst()]) q.addFirst(j);
else q.add(j);
}
}
}
}
}
static int[] source = new int[6];
static void add(int a, int b, int c) {
e[cnt] = b;
w[cnt] = c;
ne[cnt] = he[a];
he[a] = cnt++;
}
static int[] he = new int[2550];
static int[] ne = new int[6550 * 2];
static int[] e = new int[6550 * 2];
static int[] w = new int[6550 * 2];
static boolean[] vis = new boolean[2560];
static int[][] dis = new int[6][2560];
static ArrayDeque<Integer> q = new ArrayDeque<Integer>();
static int n, m, cnt = 1;
}
package com.shiyu;
package graph.复合单源最短路;
import java.util.Scanner;
public class Main {
/**
*
*/
public class 通信线路 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String next = sc.next();
System.out.println(next.toLowerCase());
n = sc.nextInt();
m = sc.nextInt();
}
}
\ No newline at end of file
static int n, m;
}
......@@ -31,7 +31,7 @@ public class 线段树 {
}
static final int maxn = 104;
static int[] tree = new int[maxn << 2];
static int[] sum = new int[maxn << 2];
static int[] tag = new int[maxn << 2];
static int[] a = new int[maxn];
static int[] min = new int[maxn << 2];
......@@ -50,14 +50,14 @@ public class 线段树 {
*/
static void build(int k, int l, int r) {
if (l == r) {
tree[k] = a[l];
sum[k] = a[l];
min[k] = a[l];
return;
}
int mid = (l + r) >> 1;
build(k << 1, l, mid);
build(k << 1 | 1, mid + 1, r);
tree[k] = tree[k << 1] + tree[k << 1 | 1];
sum[k] = sum[k << 1] + sum[k << 1 | 1];
min[k] = Math.min(min[k << 1], min[k << 1 | 1]);
}
......@@ -73,13 +73,13 @@ public class 线段树 {
*/
static void update(int k, int l, int r, int index, int value) {
if (l == r) {
tree[k] = value;
sum[k] = value;
return;
}
int mid = l + r >> 1;
if (index <= mid) update(k << 1, l, mid, index, value);
else update(k << 1 | 1, mid + 1, r, index, value);
tree[k] = tree[k << 1] + tree[k << 1 | 1];
sum[k] = sum[k << 1] + sum[k << 1 | 1];
min[k] = Math.min(min[k << 1], min[k << 1 | 1]);
}
......@@ -105,7 +105,7 @@ public class 线段树 {
*/
static long query(int k, int LL, int RR, int l, int r) {
if (LL <= l && r <= RR) {
return tree[k];
return sum[k];
}
if (tag[k] > 0) lazy(k, l, r);
int mid = (l + r) >> 1, ans = 0;
......@@ -126,7 +126,7 @@ public class 线段树 {
*/
static long ask(int k, int l, int r, int i) {
if (l == r) {
return tree[k];
return sum[k];
}
lazy(k, l, r);
int mid = (l + r) >> 1;
......@@ -150,8 +150,8 @@ public class 线段树 {
int mid = l + r >> 1;
if (tag[k] > 0) {
tag[k << 1] = tag[k << 1 | 1] = tag[k];
tree[k << 1] = (mid - l + 1) * tag[k];
tree[k << 1 | 1] = (r - mid) * tag[k];
sum[k << 1] = (mid - l + 1) * tag[k];
sum[k << 1 | 1] = (r - mid) * tag[k];
tag[k] = 0;
}
}
......@@ -161,7 +161,7 @@ public class 线段树 {
if (A <= l && r <= B) {
//当前区间[l,r]完全落在需修改区间[A,B]里面
tag[k] = v;
tree[k] = v * (r - l + 1);
sum[k] = v * (r - l + 1);
return;
}
lazy(k, l, r);
......@@ -172,7 +172,7 @@ public class 线段树 {
}
static void update(int k) {
tree[k] = tree[k << 1] + tree[k << 1 | 1];
sum[k] = sum[k << 1] + sum[k << 1 | 1];
min[k] = Math.min(min[k << 1], min[k << 1 | 1]);
}
......@@ -189,7 +189,7 @@ public class 线段树 {
static void add(int k, int A, int B, int l, int r, int v) {
if (A <= l && r <= B) {
tag[k] += v;
tree[k] += v * (r - l + 1);
sum[k] += v * (r - l + 1);
min[k] += v;
return;
}
......@@ -213,8 +213,8 @@ public class 线段树 {
if (tag[k] > 0) {
tag[k << 1] += tag[k];
tag[k << 1 | 1] += tag[k];
tree[k << 1] += (mid - l + 1) * tag[k];
tree[k << 1 | 1] += (r - mid) * tag[k];
sum[k << 1] += (mid - l + 1) * tag[k];
sum[k << 1 | 1] += (r - mid) * tag[k];
tag[k] = 0;
}
}
......
......@@ -108,9 +108,10 @@ public class 卡车加油 {
for (int i = 0; i <= N; i++) {//把终点看做加油站,看能不能到这个加油站
int d = node[i].Juli - pos;//卡车的位置从0开始,到达第i个加油站需要多少油
while (tank - d < 0) {//如果无法到达第i个加油站
if (pq.size() == 0)//从优先队列里面没有加油站,没有刻
if (pq.isEmpty()) {//从优先队列里面没有加油站,没有刻
System.out.println("-1");
tank += pq.poll();
} else
tank += pq.poll();
res++;
}
tank -= d;//减去走到第i个加油站需要的油,区间是什么呢,
......
......@@ -24,7 +24,7 @@ public class tongjizifu {
public static void main(String[] args) {
char a = 'B';
System.out.println(a + 0);
System.out.println(a);
String[] s = {"123", "asfa", "123"};
for (String bb : s) {
bb = "42";
......
package com.shiyu;
public class tsdt {
public static void main(String[] args) {
System.out.println(153);
System.out.println(370);
System.out.println(371);
System.out.println(407);
}
}
......@@ -6,9 +6,7 @@ import java.util.*;
* 带权的区间调度(挺重要,细节需要注意)
* https://blog.csdn.net/hongchh/article/details/52914507
* 存在单一资源R,有n个需求{1, 2, …, n},每个需求指定一个开始时间bi与一个结束时间ei,在时间区间[bi, ei]内该需求想要占用资源R,资源R一旦被占用则无法被其他需求利用。每个需求i带有一个权值vi,代表该需求被满足之后能够带来的价值或者贡献。如果两个需求的时间区间不重叠,那么它们是相容的。带权值的区间调度问题即,对上面所描述的情境,求出一组相容子集S使得S中的区间权值之和最大。
* <p>
* 解决此类问题一般采用动态规划的思路,执行步骤分以下几个阶段:
* <p>
* 对所有的需求按照结束时间升序排序。
* 求出所有需求前面所有的需求中和它相容的最后一个需求,记为pi。
* 若只在前i个需求中求相容子集,则可以得到的最大权值之和为M[i],
......
......@@ -80,10 +80,9 @@ public class 最大正方形 {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == 1) {
if (i == 0 || j == 0)
dp[i][j] = matrix[i][j] == 1 ? 1 : 0;//第一排,第一列,没有上面,左边,左上角来组成大正方形,直接给1
dp[i][j] = matrix[i][j] == 1 ? 1 : 0;//第一排,第一列,没有上面,左边,左上角来组成大正方形,直接给1,特判
else
dp[i][j] = Math.min(dp[i - 1][j], Math.min(dp[i][j - 1], dp[i - 1][j - 1])) + 1;
maxLength = Math.max(dp[i][j], maxLength);
}
}
......@@ -102,18 +101,18 @@ public class 最大正方形 {
* 那我们就会思考,组成一个正方形是不是必须要四个点都找到?如果我们找出其中的三个点,甚至说两个点,能不能确定这个正方形呢?
* 你会发现,这里我们只需要考虑 正方形对角线的两个点 即可,这两个点确定了,另外的两个点也就确定了,因此我们可以把时间复杂度降为 O((m*n)^2)。
* 但是这里还是会有一些重复计算在里面,我们和之前一样,本质还是在做暴力枚举,只是说枚举的个数变少了,我们能不能记录我们之前得到过的答案,通过牺牲空间换取时间呢,这里正是动态规划所要做的事情!
*
* <p>
* 我们可以思考,如果我们从左到右,然后从上到下遍历矩阵,假设我们遍历到的当前位置是正方形的右下方的点,那其实我们可以看之前我们遍历过的点有没有可能和当前点组成符合条件的正方形,除了这个点以外,无非是要找另外三个点,这三个点分别在当前点的上方,左方,以及左上方,也就是从这个点往这三个方向去做延伸,具体延伸的距离是和其相邻的三个点中的状态有关
*
* <p>
* 状态定义
*
* <p>
* 因为我们考虑的是正方形的右下方的顶点,因此状态可以定义成 “当前点为正方形的右下方的顶点时,正方形的最大面积”
*
* <p>
* 递推方程
*
* <p>
* 有了状态,我们再来看看递推方程如何写,前面说到我们可以从当前点向三个方向延伸,我们看相邻的位置的状态,这里我们需要取三个方向的状态的最小值才能确保我们延伸的是全为 ‘1’ 的正方形,也就是
*
* <p>
* dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1
*
* <p>
* 在实现上,我们需要单独考虑两种情况,就是当前位置是 ‘1’,还有就是当前位置是 ‘0’,如果是 ‘0’ 的话,状态就是 0,表示不能组成正方形,如果是 ‘1’ 的话,我们也需要考虑位置,如果是第一行的元素,以及第一列的元素,表明该位置无法同时向三个方向延伸,状态直接给为 1 即可,其他情况就按我们上面得出的递推方程来计算当前状态。
**/
\ No newline at end of file
......@@ -14,6 +14,7 @@ import java.util.Scanner;
* 15
* Sample Output
* 147
* 完全背包问题
*/
public class 最小乘车费用 {
public static void main(String[] args) {
......
......@@ -2,6 +2,9 @@ package dp;
import java.util.Arrays;
/**
* 完全背包问题
*/
public class 钢条切割 {
public static void main(String[] args) {
Arrays.fill(vs, -1);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册