惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google Online Security Blog
Google Online Security Blog
S
Security @ Cisco Blogs
Recent Commits to openclaw:main
Recent Commits to openclaw:main
人人都是产品经理
人人都是产品经理
The Hacker News
The Hacker News
W
WeLiveSecurity
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
博客园 - 司徒正美
雷峰网
雷峰网
L
LINUX DO - 最新话题
博客园 - 叶小钗
云风的 BLOG
云风的 BLOG
The Last Watchdog
The Last Watchdog
V2EX - 技术
V2EX - 技术
S
Security Affairs
有赞技术团队
有赞技术团队
月光博客
月光博客
T
Threatpost
T
Tor Project blog
O
OpenAI News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
V
V2EX
Know Your Adversary
Know Your Adversary
Project Zero
Project Zero
博客园 - 三生石上(FineUI控件)
D
Docker
AWS News Blog
AWS News Blog
AI
AI
P
Proofpoint News Feed
K
Kaspersky official blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Darknet – Hacking Tools, Hacker News & Cyber Security
www.infosecurity-magazine.com
www.infosecurity-magazine.com
S
Securelist
F
Fortinet All Blogs
F
Full Disclosure
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
量子位
Hacker News - Newest:
Hacker News - Newest: "LLM"
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
P
Palo Alto Networks Blog
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
美团技术团队
N
News | PayPal Newsroom
T
The Blog of Author Tim Ferriss
MyScale Blog
MyScale Blog

Shiroha白羽的博客

Golang 踩坑 —— interface 为参数的时候传 nil 指针 Codeforces Round 925 (Div. 3) Codeforces Round 924 (Div. 2) Codeforces Round 923 (Div. 3) Codeforces Round 922 (Div. 2) Codeforces Round 921 (Div. 2) Educational Codeforces Round 161 (Rated for Div. 2) Codeforces Round 920 (Div. 3) Codeforces Round 919 (Div. 2) Hello 2024 Good Bye 2023 Codeforces Round 918 (Div. 4) 个人备份的常用 macOS 清理命令 Codeforces Round 917 (Div. 2) Pinely Round 3 (Div. 1 + Div. 2) Educational Codeforces Round 160 (Rated for Div. 2) Codeforces Round 915 (Div. 2) Codeforces Round 914 (Div. 2) Codeforces Round 913 (Div. 3) Educational Codeforces Round 159 (Rated for Div. 2) Codeforces Round 912 (Div. 2) Codeforces Round 911 (Div. 2) CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!) Educational Codeforces Round 158 (Rated for Div. 2) Codeforces Round 910 (Div. 2) Codeforces Round 909 (Div. 3) Codeforces Round 908 (Div. 2) Educational Codeforces Round 157 (Rated for Div. 2) C++自定义的字面量 Codeforces Round 907 (Div. 2) Codeforces Round 916 (Div. 3) 关于 LRU map 的一些灵感 2023 杭州站 ICPC 现场赛 反复横跳的 Clang-Tidy(cert-dcl21-cpp) Codeforces Round 906 (Div. 2) 一段奇怪的 CPP 代码 Codeforces Round 905 (Div. 3) Codeforces Round 904 (Div. 2) Codeforces Round 903 (Div. 3) Educational Codeforces Round 156 (Rated for Div. 2) Codeforces Round 902 (Div. 2, based on COMPFEST 15 - Final Round) Codeforces Round 901 (Div. 2) Codeforces Round 900 (Div. 3) Codeforces Round 899 (Div. 2) Educational Codeforces Round#155 (Div. 2) Codeforces Round 898 (Div. 4) CodeTON Round 6 (Div. 2) Codeforces Round 897 (Div. 2) Codeforces Round 896 (Div. 2) Codeforces Round 887 (Div. 2) Codeforces Round 895 (Div. 3) 左值-右值-将亡值 blog.mauve.icu Pinely Round 2 (Div. 1 + Div. 2) Harbour.Space Scholarship Contest 2023-2024 (Div. 1 + Div. 2) Codeforces Round 894 (Div. 3) Codeforces Round 888 (Div. 3) Educational Codeforces Round#153 (Div. 2) Codeforces Round 893 (Div. 2) OTPAUTH,两步验证中的通用协议 Codeforces Round 892 (Div. 2) Codeforces Round 891 (Div. 3) Codeforces Round 890 (Div. 2) Educational Codeforces Round#152 (Div. 2) blog.mauve.icu Java Script 的 null 和 undefined 随想 记一次 SQL LEFT JOIN 没有得到预期结果的错误 Codeforces Round#789(Div. 2) GCC/G++ 预编译头性能优化 使用 Junit5 和 Mockito 实现 SpringBoot 的单元测试最优美的解决方案 centOS 防火墙 docker-compse 的问题 C++ 语言实现动态变化的线程池 Codeforces Round#744 (Div. 3) 计算机图形学 Windows 通过网络访问 WSL2 原生 JavaScript 实现图片裁剪 面试复习(计算机图形学) 面试复习(算法) Codeforces Round#706(Div. 2)-Let's Go Hiking 面试复习(Java) 面试复习(Git) 面试复习(Linux) 面试复习(数据库) 面试复习(计算机网络) 面试复习(操作系统) 面试复习(C++) 清理 WSL2 的磁盘占用 Codeforces Round#697 (Div. 3) Windows 下的 NTFS 驱动器索引 BUG 计算机网络复习 记一次 Navicat 连接 MySQL 一直报认证错误(Access denied) 计算机网络实验复习 WSL1 使用 Docker 一直无法启动 我的ACM脚印 2020牛客暑期多校训练营(第三场)D-Points Construction Problem——构造 2020牛客暑期多校训练营(第三场)E-Two Matchings——复杂思维与简单dp 2020牛客暑期多校训练营(第二场)I-Interval——最大流转对偶图求最短路 Educational Codeforces Round 80 D. Minimax Problem——二分+二进制处理 Codeforces Round 606 E. Two Fairs——图论 Codeforces Round 612 (Div. 2) C. Garland——DP
Codeforces Round#699 (Div. 2)
Shiroha · 2021-02-06 · via Shiroha白羽的博客

暂时还没有 AK,留坑

A. Space Navigation

大致题意

给你一段在棋盘上的移动指令,问能否通过在不改变原指令顺序,仅删除部分或者全部或者不删除的情况下,到达某个指定地点

分析

可以通过指令直接得出可以到达的范围,比如删除所有的“向左”指令后,能够到达的最右,同理可以得到四个方向的极值,最后判断目标地点是否在极值范围内即可

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <bits/stdc++.h>

using namespace std;

int main() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int x, y;
string str;
cin >> x >> y >> str;
int cnt[4] = {0, 0, 0, 0};
for (auto &item : str) {
switch (item) {
case 'R':
cnt[0]++;
break;
case 'L':
cnt[1]++;
break;
case 'U':
cnt[2]++;
break;
case 'D':
cnt[3]++;
break;
}
}
if (-cnt[1] <= x && x <= cnt[0] && -cnt[3] <= y && y <= cnt[2]) cout << "YES" << endl;
else cout << "NO" << endl;
}
}

B. New Colony

大致题意

给你一段台阶,然后你从第一阶开始往下面滚砖块,砖块遇到下坡就走到下一阶,遇到上坡就停止,并增加这一阶的高度。给你 $n$ 个砖块,请问最后一块砖块停止在哪里

分析

首先这道题如果不能使用暴力的话,是很麻烦的一道题。但是注意观察这道题的数据范围

$$1 \leq n \leq 100, 1 \leq k \leq 10^9, 1 \leq h_i \leq 100, \sum n \leq 100$$

假如阶梯是一直下坡或者平坡,那么砖块就会直接掉出阶梯。而如果砖块没有掉出阶梯,那么它一定会不会处于整个阶梯的最高处。所以考虑一个可能,即不断的滚落的方块将整个阶梯都填满成平地,则最多需要 $n \times h_i = 10000$ 个砖块

也就是说,当 $k > 10000$ 时,则最后一块砖块必然掉出阶梯。那么当 $k \leq 10000$ 时,暴力求解即可

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <bits/stdc++.h>

using namespace std;

#define int long long

int main() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n, k;
cin >> n >> k;
vector<int> data(n);
for (int i = 0; i < n; ++i) cin >> data[i];
if (k > 10000) cout << -1 << endl;
else {
int last = -1;
for (int i = 0; i < k; ++i) {
int cur = 0;
while (cur < n - 1 && data[cur + 1] <= data[cur]) cur++;
if (cur == n - 1) last = -1;
else {
data[cur]++;
last = cur + 1;
}
}
cout << last << endl;
}
}
}

C. Fence Painting

大致题意

一个篱笆有 $n$ 个木条组成,每个木条有一个初始的颜色。每一个木条都有一个指定的目标颜色。有 $m$ 个油漆工,每个油漆工都只携带一种颜料,按照顺序来给这个篱笆上色,他们每次必须选择一块且恰好一块木板,把它的颜色变成油漆工所携带的颜色。问每个油漆工应该选择哪一块,使得最后的木条都变成指定的颜色

分析

首先,肯定找出目前没有达到目标的木条,然后找到合适的油漆工给它上色。如果找不到合适的油漆工,那么肯定没戏

接下来是剩下的多出来的没有使用的油漆工,也需要为他们找一块木板去上色。

注意到,由于后来的可以覆盖前面的颜色,所以可以直接考虑最后那个油漆匠。

如果根据上面的操作,这个油漆匠已经有了一块木板去上色的话,那么剩下多出来的油漆工可以都给这块木板上色,这样的话,无论最后上色是什么,最后一个油漆匠一定能把这块木板染回指定的颜色。

而如果最后一个油漆工也在那些没有使用的油漆工内,那么他只需要找到一块最终颜色和自己所携带的颜色相同的,然后指定他去给这块木板上色。剩下的那些没有使用的油漆工也去给这块木板上色即可。

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <bits/stdc++.h>

using namespace std;

void solve() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n, m;
cin >> n >> m;
vector<int> a(n), b(n), c(m), res(m, 0);
map<int, vector<int>> data;
for (int i = 0; i < n; ++i) cin >> a[i];
for (int i = 0; i < n; ++i) {
cin >> b[i];
if (a[i] != b[i]) data[b[i]].push_back(i + 1);
}
for (int i = 0; i < m; ++i) cin >> c[i];
for (int i = 0; i < m; ++i) {
auto iter = data.find(c[i]);
if (iter == data.end()) continue;
res[i] = iter->second.back();
iter->second.pop_back();
if (iter->second.size() == 0) data.erase(iter);
}
if (res.back() == 0) for (int i = 0; i < n; ++i) if (c.back() == b[i]) res.back() = i + 1;
for (auto &item : res) if (item == 0) item = res.back();
if (res.back() == 0 || !data.empty()) cout << "NO" << endl;
else {
cout << "YES" << endl;
for (int i = 0; i < res.size(); ++i) cout << res[i] << " \n"[i == res.size() - 1];
}
}
}

D. AB Graph

大致题意

给你一个完全有向图,每条边都有一个字母标记,标记的字母只有可能是 “a” 或者 “b”。你需要找出一条可以包含重复点重复边的路径,满足这条路径的长度等于给定的要求,并且这条路径组成的字符串为回文串

分析

首先,由于可以有重复点和重复边,那么考虑下面的情况

如果这个图只有两个点。

此时只有两条边。如果这两条边恰好字母还相同(例如下面的 mermaid 图),那么任意长度的路径都可以画出来,只需要在这两个点之间来回走即可

graph LR
A -- a --> B
B -- a --> A

如果这两条边的字母还不相同(例如下面的 mermaid 图),那么来回的路径为奇数的时候,可以画出来,只需要在这两个点之间来回走即可

graph LR
A -- a --> B
B -- b --> A

如果这个图至少有三个点

取出整个图中任意三个点,假定这三个点为 $a, b, c$,这里定义 $g(a, b)$ 为从点 $a$ 到点 $b$ 的路径的标记字母。那么我们可以知道,一定满足 $g(a, b) = g(b, c)$ 或 $g(b, c) = g(c, a)$ 或 $g(c, a) = g(a, b)$ 其中至少一个

证明
反证法,假设上述不成立,则
由上述得 $g(a, b) \not = g(b, c)$,那么 $g(a, b)$ 与 $g(b, c)$ 相异。
由上述得 $g(b, c) \not = g(c, a)$,那么 $g(b, c)$ 与 $g(c, a)$ 相异。由于 $g(a, b)$ 与 $g(b, c)$ 相异,而所有边只有两种可能,所以 $g(c, a)$ 与 $g(b, c)$ 必定相同
由上述得 $g(c, a) \not = g(a, b)$,那么 $g(c, a)$ 与 $g(a, b)$ 相异,这与上面的结论相反,所以假设不成立,即,上述结论成立

这时,通过交换 $a, b, c$ 三个点,使得 $g(a, b) = g(b, c)$ 得到满足,则可以得到下图

graph LR
a -- x --> b
b -- x --> c
c -- y --> a

这里,我们不需要关心 $y$ 的情况,无论它是否与 $x$ 相同

这里,只需要进行 $a \rightarrow b \rightarrow c \rightarrow a$ 这样的循环,即可实现一个回文串。只需要确定是从哪一个节点开始循环即可

  • 若从 $a$ 开始循环,则得到的串为 $xxyxxyxxyxx \dots$ 当长度为 $3t + 2$ 时为回文串
  • 若从 $b$ 开始循环,则得到的串为 $xyxxyxxyxxyx \dots$ 当长度为 $3t$ 时为回文串
  • 若从 $c$ 开始循环,则得到的串为 $yxxyxxyxxyxxy \dots$ 当长度为 $3t + 1$ 时为回文串

所以只需要判断所需要的字符串长度与 $3$ 取模即可

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <bits/stdc++.h>

using namespace std;

int main() {
int _;
cin >> _;
for (int ts = 0; ts < _; ++ts) {
int n, m;
cin >> n >> m;
vector<string> g(n);
for (auto &item : g) item.reserve(n);
for (int i = 0; i < n; ++i) cin >> g[i];

if (n == 2) {
if (g[0][1] == g[1][0] || m % 2 == 1) {
cout << "YES" << endl;
for (int i = 0; i < m + 1; ++i) cout << (i % 2) + 1 << " \n"[i == m];
} else {
cout << "NO" << endl;
}
} else {
vector<int> tmp(3);
for (int i = 0; i < 3; ++i) tmp[i] = i;
do {
if (g[tmp[0]][tmp[1]] == g[tmp[1]][tmp[2]]) break;
} while (next_permutation(tmp.begin(), tmp.end()));

assert(g[tmp[0]][tmp[1]] == g[tmp[1]][tmp[2]]);
int cur = (m + 1) % 3;

cout << "YES" << endl;
for (int i = 0; i < m + 1; ++i) cout << tmp[(i + cur) % 3] + 1 << " \n"[i == m];
}
}
}

E. Sorting Books

大致题意

给你一段数列,进行如下的操作使得整个序列中相同的数字处于连续的子段中

操作:将这个数字放到整个字符串的最后

问,最少需要进行多少次操作

分析

首先,如果进行 $n$ 次操作,那么必然可以使得整个序列满足上述的要求。因为只需要按照排序后的顺序来移动所有的数字,则必定可以满足条件

那么接下来就是想办法减少次数。

如果我选出一个值,当数字与这个值相同的时候,不对其进行操作。由于其他值被移动到了最后。所以与这个值相同的值都自然而然的被移动到了最前面,例如下面这个序列

$$1, 3, 2, 2, 1, 3$$

如果我选择 $3$ 作为固定值,那么当 $1, 2$ 都进行过移动后,$3$ 自然而然的也就满足了条件

再进一步,如果稍微修改一下这个序列,将其改为

$$1, 3, 1, 2, 3, 2$$

这时,发现当我仅对 $3$ 进行移动之后,$1, 2$ 自然而然的也满足条件了。由此,可以得到一个这样的推广结论:

在某一个子区间内,如果这个子区间内存在某一个数值 $x$,满足整个区间的所有 $x$ 都在这个子区间内,那么,这个 $x$ 可以固定不动,且这个子区间内的其他所有值都需要进行操作。

所以此时可以进行 dp 求解,方法如下:

  • 找出所有值所对应的最小子区间
  • 假如这个子区间内选择这个值作为固定值,那么它所带来的代价就是这个子区间的长度减去这个值的个数
  • 由于需要进行减法比较麻烦,可以改变思路用加法,即求出有多少个值是可以固定不操作的
  • 则对于每一个区间的固定值,那么其带来的固定值数量就是这个区间内的值的个数
  • 对每一位进行 dp 求解即可

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <bits/stdc++.h>

using namespace std;

int main() {
int n;
cin >> n;
vector<int> data(n), l(n + 1, n), r(n + 1), dp(n + 1), cnt(n + 1);
for (int i = 0; i < n; ++i) {
cin >> data[i];
l[data[i]] = min(l[data[i]], i);
r[data[i]] = max(r[data[i]], i);
}
for (int i = n - 1; i >= 0; --i) {
cnt[data[i]]++;
dp[i] = max(dp[i + 1], cnt[data[i]]);
if (l[data[i]] == i) dp[i] = max(dp[i], cnt[data[i]] + dp[r[data[i]] + 1]);
}
cout << n - dp[0] << endl;
}