传送门:https://codeforces.com/problemset/problem/1328/D
题意:n个数按顺序围成一个圈(1和n连着)给每个数染色,要求相邻的不同数字颜色不可以相同,每种颜色用一个数字代替,输出最少的颜色及颜色分配
因为是要求最少的颜色,所以在1-(n-1)如果相邻且数字不同,颜色是1,那么就要变成2,如果是2,就要变成1,因为如果从2变成3就不是最优的了,如果相邻颜色不同,那就不需要变
再来考虑最后一个数,如果a[n]==a[1]那么就不需要管a[n],如果a[n]!=a[1],且b[n]!=b[1](b数组为存颜色的数组)那么也不需要管a[n],如果a[n]!=a[1],且b[n]==b[1],那么是不允许的,我们需要把b[n]的值改掉,又因为我们b[1]是从1开始的,所以此时b[n]=1,而这个1可能是从2变成的1,也可能是从1过来的1
那么再分类讨论一下就好了,如果是从1过来的,那么把b[n]=1变成2,如果是从2过来的把b[n]=2变成3,但你以为这就可以了??,不不不
这个3你也有可能把他降下来,考虑1 2 4 4 5 4这样一组数据,按照之前的思路应该输出3 ‘\n‘ 1 2 1 1 2 3对不对,但是你只要把b[5]的2往前挪一下b[5]就变成1了,那么b[6]岂不是就可以降成2
看到这里,你就可以ac了,我是如果最后一个等于3且前面有两个数连着的话把这对连着的第二个颜色改变一下,然后后面重新跑一遍判断一下(麻烦了,其实直接改就行1->2,2->1,but 别看他长,ctrl+c ctrl+v 挺方便的)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int N=1e6+9; 5 const int inf=0x3f3f3f3f; 6 int a[200009]; 7 int b[200009]; 8 int main() 9 { 10 int t; 11 scanf("%d",&t); 12 while(t--) 13 { 14 int n; 15 scanf("%d",&n); 16 for(int i=1; i<=n; i++) 17 { 18 scanf("%d",&a[i]); 19 } 20 a[n+1]=a[1]; 21 b[1]=1; 22 int maxx=1,flag=0; 23 for(int i=2; i<=n; i++) 24 { 25 if(a[i]!=a[i-1]) 26 { 27 if(b[i-1]!=1) b[i]=b[i-1]-1; 28 else b[i]=b[i-1]+1; 29 } 30 else 31 { 32 b[i]=b[i-1]; 33 } 34 if(i==n) 35 { 36 if(b[i]==1&&a[i]!=a[i+1]) 37 { 38 b[i]=b[i-1]+1; 39 flag=1; 40 } 41 } 42 if(b[i]>maxx)maxx=b[i]; 43 } 44 if(flag) 45 { 46 maxx=1; 47 int f=0; 48 for(int i=2; i<=n; i++) 49 { 50 if(b[i]==b[i-1]&&!f) 51 { 52 if(b[i]==1) b[i]++; 53 else b[i]--; 54 f=1; 55 continue; 56 } 57 if(f) 58 { 59 if(a[i]!=a[i-1]) 60 { 61 if(b[i-1]!=1) b[i]=b[i-1]-1; 62 else b[i]=b[i-1]+1; 63 } 64 else 65 { 66 b[i]=b[i-1]; 67 } 68 if(i==n) 69 { 70 if(b[i]==1&&a[i]!=a[i+1]) 71 { 72 b[i]=b[i-1]+1; 73 } 74 } 75 76 } 77 if(b[i]>maxx)maxx=b[i]; 78 } 79 } 80 printf("%d\n",maxx); 81 for(int i=1; i<=n; i++) 82 { 83 printf("%d ",b[i]); 84 } 85 printf("\n"); 86 } 87 return 0; 88 }
原文:https://www.cnblogs.com/YangKun-/p/12589786.html