Skip to content

Commit

Permalink
modified: .vscode/settings.json
Browse files Browse the repository at this point in the history
	new file:   Dijkstra.java
	renamed:    bytedance/闪充总时间计算.py -> bytedance/充电总时间计算.py
	new file:   bytedance/兔群增殖之谜.py
	new file:   bytedance/小U的生活事件快乐值最大化.py
	new file:   bytedance/最大连续子数组和问题.py
	new file:   bytedance/英雄升级与奖励最大化.py
	new file:   luogu/P1160.cpp
	modified:   test.cpp
	modified:   test.py
	new file:   test2.cpp
  • Loading branch information
sakuralggm committed Dec 17, 2024
1 parent 39eef60 commit 57a1ec4
Show file tree
Hide file tree
Showing 11 changed files with 397 additions and 28 deletions.
95 changes: 94 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,99 @@
"*.asm": "assembly",
"*.py": "python",
".clang-format": "yaml",
"ostream": "cpp"
"ostream": "cpp",
"bitset": "cpp",
"iostream": "cpp",
"any": "cpp",
"array": "cpp",
"atomic": "cpp",
"barrier": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"cfenv": "cpp",
"charconv": "cpp",
"chrono": "cpp",
"cinttypes": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"complex": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"coroutine": "cpp",
"csetjmp": "cpp",
"csignal": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cuchar": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"exception": "cpp",
"expected": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"regex": "cpp",
"source_location": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"format": "cpp",
"fstream": "cpp",
"future": "cpp",
"generator": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"istream": "cpp",
"latch": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"print": "cpp",
"ranges": "cpp",
"scoped_allocator": "cpp",
"semaphore": "cpp",
"shared_mutex": "cpp",
"span": "cpp",
"spanstream": "cpp",
"sstream": "cpp",
"stacktrace": "cpp",
"stdexcept": "cpp",
"stdfloat": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"syncstream": "cpp",
"text_encoding": "cpp",
"thread": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"valarray": "cpp",
"variant": "cpp"
}
}
40 changes: 40 additions & 0 deletions Dijkstra.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
public class Dijkstra {
public int[] findShortestPath(int[][] graph, int start) {
int n = graph.length;
int[] distances = new int[n];
boolean[] visited = new boolean[n];

// 初始化距离数组
for (int i = 0; i < n; i++) {
distances[i] = Integer.MAX_VALUE;
}
distances[start] = 0;

// 主循环
for (int count = 0; count < n - 1; count++) {
// 找到未访问节点中距离最小的
int minDistance = Integer.MAX_VALUE;
int minIndex = -1;

for (int v = 0; v < n; v++) {
if (!visited[v] && distances[v] < minDistance) {
minDistance = distances[v];
minIndex = v;
}
}

// 标记为已访问
visited[minIndex] = true;

// 更新相邻节点的距离
for (int v = 0; v < n; v++) {
if (!visited[v] && graph[minIndex][v] != 0
&& distances[minIndex] != Integer.MAX_VALUE
&& distances[minIndex] + graph[minIndex][v] < distances[v]) {
distances[v] = distances[minIndex] + graph[minIndex][v];
}
}
}
return distances;
}
}
File renamed without changes.
17 changes: 17 additions & 0 deletions bytedance/兔群增殖之谜.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
def solution(A):
# Write your code here.
if A == 1:
return 1
a, b = 1, 0
for _ in range(2, A + 1):
a, b = a + b, a
return a + b


if __name__ == "__main__":
# Add your test cases here
print(solution(2) == 2)
print(solution(5) == 8)
print(solution(1) == 1)
print(solution(15) == 987)
print(solution(50) == 20365011074)
12 changes: 12 additions & 0 deletions bytedance/小U的生活事件快乐值最大化.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
def solution(n: int, T: int, H: int, t: list, h: list, a: list) -> int:
dp = [[0] * (H + 1) for _ in range(T + 1)]
for i in range(n):
for j in range(T, t[i] - 1, -1):
for k in range(H, h[i] - 1, -1):
dp[j][k] = max(dp[j][k], dp[j - t[i]][k - h[i]] + a[i])
return dp[T][H]

if __name__ == '__main__':
print(solution(n = 2, T = 2, H = 2, t = [1, 3], h = [3, 1], a = [3, 4]) == 0)
print(solution(n = 3, T = 5, H = 5, t = [2, 1, 3], h = [1, 3, 2], a = [10, 7, 8]) == 18)
print(solution(n = 1, T = 3, H = 3, t = [4], h = [4], a = [5]) == 0)
25 changes: 25 additions & 0 deletions bytedance/最大连续子数组和问题.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# 题解:https://bytedance.larkoffice.com/docx/W4q5dpCaDok6AFxqKyUcq2Y7ndc
'''
朴素的思路:枚举替换的位置,然后计算替换后的最大子数组和
对于每个位置i,计算包含a[i]的最大子数组和的方法是先计算前面的元素的贡献和后面的元素的贡献,然后再加上max(a[i], x)。而计算贡献可以用前缀和来优化。
这道题与最大子数组和的区别在于,最大子数组和是不允许替换元素的,而这道题是允许替换元素的。对于前者,我们可以枚举每个位置i,然后计算以a[i]结尾的最大子数组和,最后取最大值。但是在这道题中,如果采用同样方法,我们就无法考虑替换后的a[i]对后面的数的贡献。因此我们枚举的是包含a[i]的最大子数组和,而不是以a[i]结尾的最大子数组和。
'''
def solution(n: int, x: int, a: list) -> int:
# 将a数组中的最小值替换为x
m = min(a)
if x < m:
a[a.index(m)] = x
pre, suf = [0] * (n + 1), [0] * (n + 1)
for i in range(n):
pre[i] = max(0, pre[i - 1] + a[i - 1] if i > 0 else 0)
for i in range(n - 1, -1, -1):
suf[i] = max(0, suf[i + 1] + a[i + 1] if i < n - 1 else 0)
return max(pre[i] + suf[i] + max(x, a[i]) for i in range(n))


if __name__ == '__main__':
print(solution(n = 5, x = 10, a = [5, -1, -5, -3, 2]) == 15)
print(solution(n = 2, x = -3, a = [-5, -2]) == -2)
print(solution(n = 6, x = 10, a = [4, -2, -11, -1, 4, -1]) == 15)
print(solution(n = 16, x = 1, a = [17,17,4,13,11,3,6,13,7,13,13,13,6,16,6,11]) == 167)
59 changes: 59 additions & 0 deletions bytedance/英雄升级与奖励最大化.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'''
题目链接:https://www.marscode.cn/practice/8ee68j852y64nl?problem_id=7414004855076470828
官方题解:https://bytedance.larkoffice.com/docx/OJSBd0oBcorDvwxxWATcF99enKb
想要获得对应的奖励,小W需要将英雄的初始能力值升级到 b_i,并且所有英雄的初始能力值都为 1,所以我们可以先对每个目标能力值 b_i 预处理出对应所需的升级次数,用数组 d 表示, d[i] 表示想达到目标值 i 所需的升级次数
在处理出 d 数组后,我们将问题转化为了:有 n 个英雄,最多通过k 次升级操作来提升英雄的能力值,然后每个英雄需要 d[b[i]]次操作,才能获得对应的奖励 c[i]。这是一个经典的01背包问题,套上模版即可通过
难点:如何处理出 d 数组
d[t]表示从1到t需要的最小操作次数
操作的规定为:
* 选择一个正整数x
* a = a + a // x (即下取整)
思路:
对于正整数t,它一定是由一个比它小的数i加上一个数i//j得到的,其中j是一个正整数。
j <= i,因为j > i时,i//j = 0,没有意义。
正向思维:我们可以枚举i和j,然后计算出t,然后更新d[t] = min(d[t], d[i] + 1),代码为:
for i in range(1, t):
for j in range(1, i + 1):
x = i + i // j
if x == t:
d[t] = min(d[i] + 1, d[t])
这是求解一个d[t]的方法。
但是我们需要求解d[1]到d[m]的值,其中m是b数组中的最大值。
因此:我们可以枚举从1到m的数,对于每个数i,我们枚举j,然后计算出它所有可以一步到达的数t,如果t <= m,那么我们就更新d[t] = min(d[i] + 1, d[t])。由于t一定是由比它小的某个数一步到达的,因此我们可以保证枚举完d[t]的所有情况,将它更新为最小。代码为:
for i in range(1, m + 1):
for j in range(1, i + 1):
t = i + i // j
if t <= m:
d[t] = min(d[i] + 1, d[t])
总结:这个思路的来源是一个数的最优解与比它小的数的最优解有关,因此我们可以从小到大递推,最终得到所有数的最优解。
'''
def solution(n, k, b, c):
m = max(b)
d = [1e9] * (m + 1)
d[1] = 0
for i in range(1, m + 1):
for j in range(1, i + 1):
t = i + i // j
if t <= m:
d[t] = min(d[i] + 1, d[t])
cost = [int(d[i]) for i in b]
# 从n个人(物品)中选,最多选k个(背包容量是k),每个人(物品)的体积是cost,价值是c
# 要求选出的物品的价值和最大
# 01背包问题
dp = [0] * (k + 1)
for i in range(n):
for j in range(k, cost[i] - 1, -1):
dp[j] = max(dp[j], dp[j - cost[i]] + c[i])
return dp[k]


if __name__ == "__main__":
# Add your test cases here
print(solution(4, 4, [1, 7, 5, 2], [2, 6, 5, 2]) == 9)
print(solution(3, 0, [3, 5, 2], [5, 4, 7]) == 0)
print(solution(3, 3, [3, 5, 2], [5, 4, 7]) == 12)
76 changes: 76 additions & 0 deletions luogu/P1160.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
这个程序实现了一个双向链表的插入和删除操作。程序首先读取一个整数 n,表示要插入的节点数量。接着读取 n-1 对整数 k 和 p,表示在节点 k 的左边或右边插入新节点。然后读取一个整数 m,表示要删除的节点数量,并读取 m 个整数表示要删除的节点。最后输出链表中剩余的节点。
具体步骤如下:
1. 定义一个结构体 Node 表示链表节点,包含左右指针。
2. 定义一个数组 q 存储链表节点,数组 has_deleted 标记节点是否被删除。
3. 实现插入和删除操作的函数 insert 和 remove。
4. 在主函数中读取输入,执行插入和删除操作,最后输出链表中剩余的节点。
*/

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using pii = pair<int, int>;

const int N = 1e5 + 10;

// 定义链表节点结构体
struct Node
{
int l, r; // 左右指针
};
Node q[N]; // 存储链表节点的数组
bool has_deleted[N]; // 标记节点是否被删除

// 在节点 a 的右边插入节点 x
void insert(int a, int x)
{
q[x].r = q[a].r; // x 的右指针指向 a 的右指针指向的节点
q[x].l = a; // x 的左指针指向 a
q[q[a].r].l = x; // a 的右指针指向的节点的左指针指向 x
q[a].r = x; // a 的右指针指向 x
}

// 删除节点 x
void remove(int x)
{
q[q[x].l].r = q[x].r; // x 的左指针指向的节点的右指针指向 x 的右指针指向的节点
q[q[x].r].l = q[x].l; // x 的右指针指向的节点的左指针指向 x 的左指针指向的节点
}

int main()
{
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); // 关闭同步,加快读入输入的速度

int n;
cin >> n; // 读取节点数量

// 将0作为链表的头节点(不存数据),数据从1开始。数组下标就是节点的编号
q[0].r = 1; // 初始化链表头节点,0的右边是1
q[1].l = 0, q[1].r = -1; // 初始化链表第一个节点,1·的左边是0,右边设为-1,表示链表结束。
for (int i = 2; i <= n; i++)
{
int k, p;
cin >> k >> p; // 读取插入位置和方向
if (p == 0) insert(q[k].l, i); // 在 k 的左边插入 i,在k的左边就是在k的左节点的右边插入i
else insert(k, i); // 在 k 的右边插入 i
}
int m;
cin >> m; // 读取要删除的节点数量
for (int i = 0; i < m; i++)
{
int x;
cin >> x; // 读取要删除的节点
if (has_deleted[x]) continue; // 如果节点已经被删除,跳过
else
{
has_deleted[x] = true; // 标记节点已删除
remove(x); // 删除节点
}
}
for (int i = q[0].r; i != -1; i = q[i].r) // 输出链表中剩余的节点,前面说过,0是头节点,0的右边是第一个节点。之前把1号的节点的右节点设为-1,标志结束。那在插入的时候,尾结点左边插入的话,-1可以标志结束。在尾结点右边插入的话,新的尾结点的右节点还是-1,删除时同理。因此在我们的插入和删除操作中,一直维护了-1作为链表的结束标志这一个特性。
cout << i << ' ';
return 0;
}
Loading

0 comments on commit 57a1ec4

Please sign in to comment.