Skip to content

Commit 26a5b0c

Browse files
update
1 parent 3c1b7b7 commit 26a5b0c

15 files changed

+518
-9
lines changed

problems/kamacoder/0047.参会dijkstra堆.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,104 @@ int main() {
655655

656656
### Java
657657

658+
```Java
659+
660+
import java.util.*;
661+
662+
class Edge {
663+
int to; // 邻接顶点
664+
int val; // 边的权重
665+
666+
Edge(int to, int val) {
667+
this.to = to;
668+
this.val = val;
669+
}
670+
}
671+
672+
class MyComparison implements Comparator<Pair<Integer, Integer>> {
673+
@Override
674+
public int compare(Pair<Integer, Integer> lhs, Pair<Integer, Integer> rhs) {
675+
return Integer.compare(lhs.second, rhs.second);
676+
}
677+
}
678+
679+
class Pair<U, V> {
680+
public final U first;
681+
public final V second;
682+
683+
public Pair(U first, V second) {
684+
this.first = first;
685+
this.second = second;
686+
}
687+
}
688+
689+
public class Main {
690+
public static void main(String[] args) {
691+
Scanner scanner = new Scanner(System.in);
692+
int n = scanner.nextInt();
693+
int m = scanner.nextInt();
694+
695+
List<List<Edge>> grid = new ArrayList<>(n + 1);
696+
for (int i = 0; i <= n; i++) {
697+
grid.add(new ArrayList<>());
698+
}
699+
700+
for (int i = 0; i < m; i++) {
701+
int p1 = scanner.nextInt();
702+
int p2 = scanner.nextInt();
703+
int val = scanner.nextInt();
704+
grid.get(p1).add(new Edge(p2, val));
705+
}
706+
707+
int start = 1; // 起点
708+
int end = n; // 终点
709+
710+
// 存储从源点到每个节点的最短距离
711+
int[] minDist = new int[n + 1];
712+
Arrays.fill(minDist, Integer.MAX_VALUE);
713+
714+
// 记录顶点是否被访问过
715+
boolean[] visited = new boolean[n + 1];
716+
717+
// 优先队列中存放 Pair<节点,源点到该节点的权值>
718+
PriorityQueue<Pair<Integer, Integer>> pq = new PriorityQueue<>(new MyComparison());
719+
720+
// 初始化队列,源点到源点的距离为0,所以初始为0
721+
pq.add(new Pair<>(start, 0));
722+
723+
minDist[start] = 0; // 起始点到自身的距离为0
724+
725+
while (!pq.isEmpty()) {
726+
// 1. 第一步,选源点到哪个节点近且该节点未被访问过(通过优先级队列来实现)
727+
// <节点, 源点到该节点的距离>
728+
Pair<Integer, Integer> cur = pq.poll();
729+
730+
if (visited[cur.first]) continue;
731+
732+
// 2. 第二步,该最近节点被标记访问过
733+
visited[cur.first] = true;
734+
735+
// 3. 第三步,更新非访问节点到源点的距离(即更新minDist数组)
736+
for (Edge edge : grid.get(cur.first)) { // 遍历 cur指向的节点,cur指向的节点为 edge
737+
// cur指向的节点edge.to,这条边的权值为 edge.val
738+
if (!visited[edge.to] && minDist[cur.first] + edge.val < minDist[edge.to]) { // 更新minDist
739+
minDist[edge.to] = minDist[cur.first] + edge.val;
740+
pq.add(new Pair<>(edge.to, minDist[edge.to]));
741+
}
742+
}
743+
}
744+
745+
if (minDist[end] == Integer.MAX_VALUE) {
746+
System.out.println(-1); // 不能到达终点
747+
} else {
748+
System.out.println(minDist[end]); // 到达终点最短路径
749+
}
750+
}
751+
}
752+
753+
```
754+
755+
658756
### Python
659757

660758
### Go

problems/kamacoder/0047.参会dijkstra朴素.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,73 @@ for (int v = 1; v <= n; v++) {
737737

738738
### Java
739739

740+
```Java
741+
import java.util.Arrays;
742+
import java.util.Scanner;
743+
744+
public class Main {
745+
public static void main(String[] args) {
746+
Scanner scanner = new Scanner(System.in);
747+
int n = scanner.nextInt();
748+
int m = scanner.nextInt();
749+
750+
int[][] grid = new int[n + 1][n + 1];
751+
for (int i = 0; i <= n; i++) {
752+
Arrays.fill(grid[i], Integer.MAX_VALUE);
753+
}
754+
755+
for (int i = 0; i < m; i++) {
756+
int p1 = scanner.nextInt();
757+
int p2 = scanner.nextInt();
758+
int val = scanner.nextInt();
759+
grid[p1][p2] = val;
760+
}
761+
762+
int start = 1;
763+
int end = n;
764+
765+
// 存储从源点到每个节点的最短距离
766+
int[] minDist = new int[n + 1];
767+
Arrays.fill(minDist, Integer.MAX_VALUE);
768+
769+
// 记录顶点是否被访问过
770+
boolean[] visited = new boolean[n + 1];
771+
772+
minDist[start] = 0; // 起始点到自身的距离为0
773+
774+
for (int i = 1; i <= n; i++) { // 遍历所有节点
775+
776+
int minVal = Integer.MAX_VALUE;
777+
int cur = 1;
778+
779+
// 1、选距离源点最近且未访问过的节点
780+
for (int v = 1; v <= n; ++v) {
781+
if (!visited[v] && minDist[v] < minVal) {
782+
minVal = minDist[v];
783+
cur = v;
784+
}
785+
}
786+
787+
visited[cur] = true; // 2、标记该节点已被访问
788+
789+
// 3、第三步,更新非访问节点到源点的距离(即更新minDist数组)
790+
for (int v = 1; v <= n; v++) {
791+
if (!visited[v] && grid[cur][v] != Integer.MAX_VALUE && minDist[cur] + grid[cur][v] < minDist[v]) {
792+
minDist[v] = minDist[cur] + grid[cur][v];
793+
}
794+
}
795+
}
796+
797+
if (minDist[end] == Integer.MAX_VALUE) {
798+
System.out.println(-1); // 不能到达终点
799+
} else {
800+
System.out.println(minDist[end]); // 到达终点最短路径
801+
}
802+
}
803+
}
804+
805+
```
806+
740807
### Python
741808

742809
### Go

problems/kamacoder/0098.所有可达路径.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,19 @@
7575

7676
## 插曲
7777

78+
-------------
79+
80+
本题和力扣 [797.所有可能的路径](https://leetcode.cn/problems/all-paths-from-source-to-target/description/) 是一样的,录友了解深度优先搜索之后,这道题目就是模板题,是送分题。
81+
82+
力扣是核心代码模式,把图的存储方式给大家定义好了,只需要写出深搜的核心代码就可以。
83+
84+
如果笔试的时候出一道原题 (笔试都是ACM模式,部分面试也是ACM模式),不少熟练刷力扣的录友都难住了,因为不知道图应该怎么存,也不知道自己存的图如何去遍历。
85+
86+
所以这也是为什么我要让大家练习 ACM模式
87+
88+
--------
89+
90+
7891
这道题目是深度优先搜索,比较好的入门题。
7992

8093
如果对深度优先搜索还不够了解,可以先看这里:[深度优先搜索的理论基础](https://programmercarl.com/图论深搜理论基础.html)

problems/kamacoder/0110.字符串接龙.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
# 110. 字符串接龙
55

6-
[卡码网题目链接(ACM模式)](https://kamacoder.com/problempage.php?pid=1182)
6+
[卡码网题目链接(ACM模式)](https://kamacoder.com/problempage.php?pid=1183)
77

88
题目描述
99

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
# 111. 构造二阶行列式
3+
4+
暴力模拟就好,每个数不超过 20, 暴力枚举其实也没多大。
5+
6+
```CPP
7+
#include <iostream>
8+
using namespace std;
9+
int main() {
10+
int n;
11+
cin >> n;
12+
for (int x = 1; x <= 20; x++) {
13+
for (int y = 1; y <= 20; y++) {
14+
for (int i = 1; i <= 20; i++) {
15+
for (int j = 1; j <= 20; j++) {
16+
if ((x * j - y * i) == n) {
17+
cout << x << " " << y << endl;
18+
cout << i << " " << j << endl;
19+
return 0;
20+
}
21+
}
22+
}
23+
}
24+
}
25+
cout << -1 << endl;
26+
}
27+
```

problems/kamacoder/0112.挑战boss.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
# 112. 挑战boss
3+
4+
本题题意有点绕,注意看一下 题目描述中的【提示信息】,但是在笔试中,是不给这样的提示信息的。
5+
6+
简单模拟:
7+
8+
```CPP
9+
#include<iostream>
10+
using namespace std;
11+
int main() {
12+
int n, a, b, k = 0;
13+
cin >> n >> a >> b;
14+
string s;
15+
cin >> s;
16+
int result = 0;
17+
for (int i = 0; i < s.size(); i++) {
18+
int cur = a + k * b;
19+
result += cur;
20+
++k;
21+
if (s[i] == 'x') k = 0;
22+
}
23+
cout << result << endl;
24+
return 0;
25+
}
26+
```
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
# 114. 小欧的平均数
3+
4+
这道题非常的脑筋急转弯, 读题都要理解半天。
5+
6+
初步读题,感觉好像是求 如何最小加减,得到三个数的平均数。
7+
8+
但题意不是这样的。
9+
10+
小欧的说的三个数平衡,只是三个数里 任何两个数 相加都能被2整除, 那么 也就是说,这三个数 要么都是 奇数,要么都是偶数,才能达到小欧所说的平衡。
11+
12+
所以题目要求的,就是,三个数,最小加减1 几次 可以让三个数都变成奇数,或者都变成偶数。
13+
14+
所以最终的结果 不是1 就是0,没有其他的。
15+
16+
录友可能想,题目出的这么绕干啥? 没办法,企业的笔试题就是这样的。
17+
18+
```CPP
19+
#include<iostream>
20+
#include<algorithm>
21+
using namespace std;
22+
int main() {
23+
int x, y, z;
24+
cin >> x >> y >> z;
25+
int count = (x % 2 == 0) + (y % 2 == 0) + (z % 2 == 0);
26+
cout << min(3 - count, count);
27+
}
28+
```
29+
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
2+
# 115. 组装手机
3+
4+
这道题是比较难得哈希表题目。 把代码随想录哈希表章节理解透彻,做本题没问题。
5+
6+
思路是
7+
8+
1. 用哈希表记录 外壳售价 和 手机零件售价 出现的次数
9+
2. 记录总和出现的次数
10+
3. 遍历总和,减去 外壳售价,看 手机零件售价出现了几次
11+
4. 最后累加,取最大值
12+
13+
有一个需要注意的点: 数字可以重复,在计算个数的时候,如果计算重复的数字
14+
15+
例如 如果输入是
16+
17+
```
18+
4
19+
1 1 1 1
20+
1 1 1 1
21+
```
22+
那么输出应该是 4, 外壳售价 和 手机零件售价 是可以重复的。
23+
24+
代码如下:
25+
26+
```CPP
27+
#include <iostream>
28+
#include <vector>
29+
#include <unordered_set>
30+
#include <unordered_map>
31+
using namespace std;
32+
int main() {
33+
int n;
34+
cin >> n;
35+
vector<int> aVec(n, 0);
36+
vector<int> bVec(n, 0);
37+
unordered_map<int, int > aUmap;
38+
unordered_map<int, int > bUmap;
39+
for (int i = 0; i < n; i++) {
40+
cin >> aVec[i];
41+
aUmap[aVec[i]]++;
42+
}
43+
for (int i = 0; i < n; i++) {
44+
cin >> bVec[i];
45+
bUmap[bVec[i]]++;
46+
}
47+
unordered_set<int > uset;
48+
for (int i = 0; i < n; i++) {
49+
for (int j = 0; j < n; j++){
50+
uset.insert(aVec[i] + bVec[j]);
51+
}
52+
}
53+
int result = 0;
54+
for (int sum : uset) {
55+
//cout << p.first << endl;
56+
int count = 0;
57+
for (pair<int, int> p : aUmap) {
58+
//cout << p.first - aVec[i] << endl;
59+
if (sum - p.first > 0 && bUmap[sum - p.first] != 0) {
60+
count += min(bUmap[sum - p.first], p.second);
61+
}
62+
}
63+
result = max(result, count);
64+
}
65+
cout << result << endl;
66+
}
67+
```

problems/kamacoder/0126.骑士的攻击astar.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ x1, x2 为起点坐标,y1, y2 为终点坐标 ,abs 为求绝对值,sqrt
192192

193193
计算出来 F 之后,按照 F 的 大小,来选去出队列的节点。
194194

195-
可以使用 优先级队列 帮我们排好序,每次出队列,就是F最大的节点
195+
可以使用 优先级队列 帮我们排好序,每次出队列,就是F最小的节点
196196

197197
实现代码如下:(启发式函数 采用 欧拉距离计算方式)
198198

problems/kamacoder/小美的排列询问.md renamed to problems/kamacoder/0127.小美的排列询问.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

2-
小美的排列询问
2+
# 小美的排列询问
33

4-
注意 x 和y 不分先后
4+
模拟题,注意 x 和y 不分先后
55

66
```CPP
77

0 commit comments

Comments
 (0)