Codeforces Round 885 (Div. 2) B

B. 维卡和木桥

每个测试的时间限制为1秒
每个测试的内存限制为256兆字节
输入:标准输入
输出:标准输出

夏天,维卡喜欢去她的乡间别墅。那里有一切供放松的设施:舒适的秋千、自行车和一条河流。

河上有一座木桥,由n块木板组成。它相当老旧而不吸引人,所以维卡决定给它上漆。在小屋里,他们找到了k种颜色的油漆罐。

在将每块木板涂成k种颜色之后,维卡正准备休息一下,去荡秋千。然而,她意识到别墅在河的另一边,油漆还没有完全干透,所以她暂时不能走在桥上。

为了不破坏桥的外观,维卡决定她还是会走在桥上,但只会踩在相同颜色的木板上。否则,她脚底上的一层油漆会破坏另一种颜色的木板。维卡还剩下一点点油漆,但只够给桥上的一块木板重新上色。

现在,维卡站在第一块木板前的地面上。为了穿过桥,她将选择一些相同颜色的木板(重新上色后),这些木板的编号为1≤i1<i2<…<im≤n(木板从左到右编号为1)。然后,维卡将穿过每个步骤中的i1−1,i2−i1−1,i3−i2−1,…,im−im−1−1,n−im块木板。

由于维卡害怕跌倒,她不想迈出太大的步子。帮助她并告诉她,如果在穿过桥的过程中可以重新上色一块(或零块)木板,那么她将不得不一次穿过的木板数量的最小可能的最大值是多少。

输入

每个测试由多个测试用例组成。第一行包含一个整数t(1≤t≤104)- 测试用例的数量。接下来是各个测试用例的描述。

每个测试用例的第一行包含两个整数n和k(1≤k≤n≤2⋅105)- 桥上木板的数量和不同颜色的油漆的数量。

每个测试用例的第二行包含n个整数c1,c2,c3,…,cn(1≤ci≤k)- 维卡给桥上木板上的颜色。

保证所有测试用例中n的总和不超过2⋅105。

输出

对于每个测试用例,输出一个整数- 维卡一次步行中将要跨越的木板数量的最小可能的最大值。

样例

input

5
5 2
1 1 2 1 1
7 3
1 2 3 3 3 2 1
6 6
1 2 3 4 5 6
8 4
1 2 3 4 2 3 1 4
3 1
1 1 1

output

0
1
2
2
0

NOTE

在第一个测试用例中,维卡可以将中间的木板重新上色为颜色1,然后在桥上行走而无需踩过任何木板。

在第二个测试用例中,维卡可以将中间的木板重新上色为颜色2,然后在桥上行走,每次只需踩过一块木板。

在第三个测试用例中,维卡可以将倒数第二块木板重新上色为颜色2,然后在桥上行走,只踩到编号为2和5的木板上。然后,每次维卡需要踩过1、2和1块木板,因此答案是2。

在第四个测试用例中,维卡可以直接在桥上行走而不重新上色木板,每次踩过两块木板,走在颜色为3的木板上。

在第五个测试用例中,维卡可以直接在桥上行走而不重新上色木板,而且无需踩过任何木板。

分析:

在通过数组的单次线性遍历中,让我们为每种颜色计算该颜色的木板之间的两个最大步长的长度。为此,我们将保留上次遇到该颜色的时间。现在我们需要考虑是否可以重新粉刷其中一板。假设我们将一块木板重新涂上颜色C。很容易注意到,我们应该在颜色木板之间最长的台阶中间重新绘制木板C。毕竟,如果我们不重新粉刷这样的木板,我们仍然需要迈出最长的一步。

因此,固定颜色的答案将是两个值中的最大值:该颜色的木板之间最长台阶长度的一半,以及该颜色木板之间第二大台阶的长度。

知道每种颜色的答案,我们就可以确定问题的答案。为此,我们只需取所有颜色答案的最小值即可。

CODE

#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int n, k;
cin >> n >> k;
vector<int> c(n);
for (int i = 0; i < n; ++i) {
cin >> c[i];
}
vector<int> last(k, -1);//记录上一个颜色的为自己
vector<int> max_step(k), max2_step(k);////每种颜色最大间距和第二大的间距
for (int i = 0; i < n; ++i) {
int step = i - last[c[i] - 1];//step就是当前位置上的颜色与上一个同种颜色之间的距离
if (step > max_step[c[i] - 1]) {//如果step大于之前存的距离就更新
max2_step[c[i] - 1] = max_step[c[i] - 1];
max_step[c[i] - 1] = step;
} else if (step > max2_step[c[i] - 1]) {
max2_step[c[i] - 1] = step;
}
last[c[i] - 1] = i;
}
for (int i = 0; i < k; ++i) {
int step = n - last[i];
if (step > max_step[i]) {
max2_step[i] = max_step[i];
max_step[i] = step;
} else if (step > max2_step[i]) {
max2_step[i] = step;
}
}
int ans = 1e9;
for (int i = 0; i < k; ++i) {
ans = min(ans, max((max_step[i] + 1) / 2, max2_step[i]));//答案就是对每一种颜色都进行讨论,讨论每种颜色最大距离的1/2和第二大距离之间的最大值
}
cout << ans - 1 << "\n";
}
return 0;
}
posted @   liuwansi  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示