题目简意
有一座桥,桥上由多个木板组成,木板上有颜色,可能相同可能不同,可以修改一块木板的颜色(不是非要改),求同种颜色木板之间最大距离的最小值。
分析
假设我们已经知道了同种木板之间的最大距离
x
x
x,和次大距离
y
y
y,那么显然把最大距离中间的一块木板改变颜色就可以最小化答案,接下来的最大距离就是:
max
{
⌊
x
2
⌋
,
y
}
\max\{\lfloor {x\over 2} \rfloor,y\}
max{⌊2x⌋,y}。
那我们只要把最大值于次大值给预处理出来就行了。
于是就有了代码:
#include <iostream>
#include <cstdio>
using namespace std;
#define maxn 1000005
int semax[maxn], frmax[maxn];
// 次大值semax,最大值frmax.
int last[maxn];
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t, n, m;
cin >> t;
while (t--) {
cin >> n >> m;
// 这边有点类似于次短路的求法
for (int i = 1, x; i <= n; i++) {
cin >> x;
int dist = i - last[x] - 1;
if (dist > frmax[x]) {
semax[x] = frmax[x];
frmax[x] = dist;
} else if (dist > semax[x]) {
semax[x] = dist;
}
last[x] = i;
}
for (int i = 1; i <= m; i++) {
int dist = n - last[i];
if (dist > frmax[i]) {
semax[i] = frmax[i];
frmax[i] = dist;
} else if (dist > semax[i]) {
semax[i] = dist;
}
}
int ans = (1 << 30);
for (int i = 1; i <= m; i++) {
ans = min(ans, max(semax[i], frmax[i] >> 1));
}
cout << ans << '\n';
for (int i = 1; i <= m; i++) {
last[i] = semax[i] = frmax[i] = 0;
}
}
}