给一个环,在保证相邻且类型不同的元素颜色不同的情况下,求环的最小涂色数。
一:如果1种类型元素,那就用1种颜色即可。
二:排除第一种情况后,剩下至少有1对相邻不相同的元素。
(1)n的大小为偶数,那就可以构造 1 2 1 2。。。的环,保证无相邻颜色相同。
(2)n的大小为奇数,如果有相邻相同的元素,对其中一对相邻元素取相同颜色,也可以看成合二为一,那实则转化为上述情况。
如果没有,那就表示至少要3种。那就1 2 1 2 。。。。3。
const int N = 2e5 + 5;
int t;
int a[N];
int main()
{
cin >> t;
while (t--)
{
int n;
scanf("%d", &n);
int fg = 1;
scanf("%d", &a[1]);
int k = 1;
f(i, 2, n) { scanf("%d", &a[i]);if (a[i] != a[i - 1]) { fg = 2; } else k = 2; }
if (a[1] != a[n])fg = 2;else k = 2;
if (fg == 1) { puts("1");f(i, 1, n)printf("%d ", 1);puts(""); continue; }
if (n % 2 == 0)
{
puts("2");
f(i, 1, n / 2)printf("1 2 ");
puts("");
}
else//有重复元素合并一个就和第二种情况一致了,保证后序相邻都不同,否则1 2 1 3
{
if (k == 1)
{
puts("3");
f(i, 1, n / 2)printf("1 2 ");
puts("3");
}
else
{
puts("2");
int i;
for (i = 1;i <= n;i++)
{
if (a[i] == a[i - 1])break;
else
{
if (i & 1)printf("1 ");
else printf("2 ");
}
}
f(j, i, n)
{
if (j & 1)printf("2 ");
else printf("1 ");
}
puts("");
}
}
}
return 0;
}