问题描述
小蓝是一位有名的漆匠,他的朋友小桥有一个漆房,里面有一条长长的走廊,走廊两旁有许多相邻的房子,每间房子最初被涂上了一种颜色。小桥来找小蓝,想让他把整个走廊都涂成同一个颜色。小蓝告诉小桥,他每天只能涂一段长度为 k 的区间。对于每个区间,他可以选择将其中的房子重新涂上任何一种颜色,或者保持原来的颜色不变。小桥想知道小蓝至少要涂几天,才能让整个走廊变得美丽。
输入两行,第一行一个整数表示测试用例的数量
每个测试用例的第一行包含两个整数n和k
第二行包含n个整数,分别表示每个房子最初的颜色。
输出一个整数,表示小蓝需要涂漆的最少天数。
输入样例
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() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
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;
}
ans = min(ans, cnt);
}
cout << ans << endl;
}
return 0;
}
首先,输入t表示测试样例的数量,接着输入n,k表示房子数量和一天至多能涂的房子数。
定义一个vector为vector<int>arr(n); (n)
在vector<int>arr(n)
被用来指定向量arr
的初始大小为n
。这是必要的,因为在后续的循环中会向向量中添加元素。因此此时(n)不能省略。
定义一个无序集合unordered_set<int>s;用来存储房子的颜色,并且保证后续遍历时颜色不重复,因此使用无序集合。
定义一个ans表示最终答案,初始化为INT_MAX,INX_MAX为c++库中自带的表示int型中的最大整数。令ans=INT_MAX的目的是 后续在遍历涂每种颜色所需天数时,找到最少的天数。相当于一个参数,用于进行比较大小。
接着使用双层循环进行遍历,外层循环遍历每种颜色,内层循环遍历每个房子,每遍历一种颜色时,若(arr[j]==x),即该房子颜色为该颜色,就跳过,继续遍历下一个房子。若不是该颜色,就cnt+1,表示所需天数+1,又因为这一天最多能涂k个房子,所以让内层循环 j +上k-1,因为 j 本身就++,所以k-1。每遍历完一种颜色,外层循环就执行一次ans=min(ans,cnt),知道遍历完成所有颜色,找到所需最少的天数,输出即可。