首先,我想到了二分答案的方法,但写不出check函数,如果有大佬愿意的话,希望能够分享一下。
之后,我们可以分析题意得知,这是从0~n+1这么多个位置进行跳跃,每一次都只能跳到颜色相同的板子上面,但我们能够将其中一块板子的颜色更改掉。
于是,我们自然想到了将每一个板子的最大跳跃距离都求出来,然后通过更新找到最大值最小。
怎么求出每一个板子的最大跳跃距离呢?
实际上我们只需要不断枚举更新即可。
但别忘了我们还有一次将最大距离变为二分之一的机会,所以我们还需要求出次大距离,那么在掌握这些之后,所有就易如反掌了。
细节问题,我们还要注意这是从0~n+1的问题,如果我们不注意N+1与上一个木板的间隔的话,就会wa.,
嗯,没了。
#include <bits/stdc++.h>
using namespace std;
const int N = 200050;
int a[N];
int maxju[N];
int cimax[N];
int last[N];
int main() {
int t;
cin >> t;
while (t--) {
int n, k;
cin >> n >> k;
for (int i = 1; i <= k; i++) {
last[i] = 0;
maxju[i] = 0;
cimax[i] = 0;
}
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++) {
if (i - last[a[i]] - 1 > maxju[a[i]]) {
cimax[a[i]] = maxju[a[i]];
maxju[a[i]] = i - last[a[i]] - 1;
} else if (i - last[a[i]] - 1 > cimax[a[i]])
cimax[a[i]] = i - last[a[i]] - 1;
last[a[i]] = i;
}
for (int i = 1; i <= k; i++) {
if (n + 1 - last[i] - 1 > maxju[i]) {
cimax[i] = maxju[i];
maxju[i] = n + 1 - last[i] - 1;
} else if (n + 1 - last[i] - 1 > cimax[i])
cimax[i] = n + 1 - last[i] - 1;
}
for (int i = 1; i <= k; i++) {
maxju[i] /= 2;
maxju[i] = max(maxju[i], cimax[i]);
}
int ans = n;
for (int i = 1; i <= k; i++) {
ans = min(ans, maxju[i]);
}
cout << ans << "\n";
}
return 0;
}