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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理