题意: 给出一个环,环上有n个数字,要求在环上相邻且不同的两个数字必须用不同的颜色涂色(相邻且相同的数字随便涂)。求满足条件的情况下最少需要多少种颜色,并输出任意一种结果。
思路:
首先必须在看到题目以后想到一条性质——无论什么情况最多只需要用3种颜色涂色即可,因为对于(i-1,i,i+1)这三个数字而言i-1,i是不会影响后续的(i+1,i+2,i+3)选择的。如果想不到这条性质那么很难入手解题。。。
其次容易想到的是如果只用一种颜色涂色,那么n个数字一定是相等的。
那么难点就是判断什么时候用两种颜色什么时候用三种颜色了。。。显然的一种想法是我们可以先假设只涂两种颜色,并按照相邻的情况下相同涂同种颜色,不同涂另外一种颜色的思路从1涂到n,之后判断1和n是否会出现冲突。
当然这种思路是错误的,当输入 n=4 {1,2,2,3}时显然1与最后一个3是会冲突。因为题目没有规则相邻且相同的数字一定要涂同种颜色,所以当出现相邻且连续相同的数字时我们可以在出现上述冲突的情况下,将这个连续且相同的序列最后一位及之后数字反转,此时如果仍不成立,那么一定是需要三种颜色,只需要将最后一位设为3即可。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int t,n,sb,last; 5 int Out[2000005]; 6 7 int main(){ 8 scanf("%d", &t); 9 while(t--){ 10 int flag = 0, k = 1; 11 scanf("%d%d", &n, &last); 12 int One = last; 13 Out[0] = 1; 14 for(int i = 1; i < n; i++){ 15 scanf("%d", &sb); 16 if(last == sb) Out[i] = Out[i - 1], flag = i; 17 else Out[i] = 3 - Out[i - 1], k = 2; 18 last = sb; 19 } 20 if(Out[n - 1] == 1 && last != One && k == 2){ 21 if(flag != 0) for(int i = flag; i < n; i++) Out[i] = 3 - Out[i - 1]; 22 else k = 3, Out[n - 1] = 3; 23 } 24 printf("%d\n",k); 25 for(int i = 0; i < n; i++) printf("%d ", Out[i]); 26 puts(""); 27 } 28 return 0; 29 }