输入
2
5 2
1 1 2 2 1
6 2
1 2 2 3 3 3
输出
1
2
#include <bits/stdc++.h>
using namespace std;
int main() {
int t; cin >> t;
for (int i = 0, n, k; i < t; i++) {
cin >> n >> k;
vector<int> arr(n);
unordered_set<int> s;
for (int j = 0; j < n; j++) {
cin >> arr[j];
s.insert(arr[j]); //一个集合,防止重复记录
}
int ans = INT_MAX;
for(auto &x : s) {
int cnt = 0;
for(int j = 0; j < n; j++) {
if(arr[j] == x) continue; //如果当前颜色和我要涂的颜色一样,那么跳过
cnt += 1;
j += k - 1; //否则将k区间内的颜色全部涂该种颜色,由于上面有j++,这里要-1
}
ans = min(ans, cnt); //记录最小的就是答案
}
cout << ans << endl;
}
return 0;
}
这段代码的目的是解决前面提到的问题:计算小蓝至少需要多少天才能将走廊上所有房子涂成相同的颜色。代码逻辑如下:
代码首先读入测试用例的个数t
。
对于每个测试用例,代码读入两个整数n
和k
,分别表示房子的数量和每天可涂漆的区间长度。
接下来,代码初始化一个整型向量arr
来存储每个房子的颜色,并创建一个集合s
来存储所有独特的颜色(防止重复)。
然后,代码使用一个嵌套循环来遍历集合s
中的每一种颜色,检查如果将走廊上所有房子涂成该颜色,需要多少天。
外层的for
循环遍历集合s
中的每一种颜色。对于每一种颜色:
cnt
用来计数需要涂漆的天数。for
循环遍历整个走廊,检查每个房子的颜色:
x
,那么不执行任何操作。x
,那么cnt
加1(表示需要再涂一天),并且将索引j
增加k
-1,这是因为我们假设在这一天我们涂了从房子j
开始的k
长度的区间。在检查完所有房子之后,外层循环更新ans
为所有尝试中的最小天数。
最后,代码输出最小天数ans
作为这个测试用例的答案。
代码使用了unordered_set
来去除重复的颜色,并且使用INT_MAX
来初始化ans
确保能找到最小的天数。在每一轮的尝试中,代码都会尝试将整个走廊涂成一种颜色,并计算涂成该颜色所需的最小天数。代码利用了贪心的思路,即每次都会尽可能多地涂漆以减少涂漆的总天数。
这种方法的时间复杂度是O(nm),其中n
是房子的数量,m
是不同颜色的数量。在最坏的情况下,这个算法可能会有些慢,但考虑到题目中给出的最大n
为10^4
和颜色总数不超过60,这个方法在实践中是可行的。