题意
N个数的序列,每次可以将一个数移动至开头。问最少多少次操作可以使序列中没有相邻相同项。
T<=100, N<=1000
题解
先检查是否有数字超过一半。
记录各个数字需要移动的数字个数。若没有数字超过一半,则答案为需要移动数字个数之和;否则需要从剩下的序列中移动数字,特判开头的情况即可。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int a[1010], cnt[1010]; 5 6 int main() 7 { 8 int T; 9 scanf("%d", &T); 10 while (T--) 11 { 12 memset(cnt, 0, sizeof(cnt)); 13 int n; 14 scanf("%d", &n); 15 for (int i = 0; i < n; ++i) 16 { 17 scanf("%d", a + i); 18 cnt[a[i]]++; 19 } 20 bool pd(0); 21 for (int i = 1; i <= n; ++i) 22 if (cnt[i] > (n + 1) / 2) 23 pd = 1; 24 if (pd) 25 { 26 puts("-1"); 27 continue; 28 } 29 30 memset(cnt, 0, sizeof(cnt)); 31 int sum(0), duo(-1); 32 for (int i = 1; i < n; ++i) 33 if (a[i] == a[i - 1]) 34 { 35 cnt[a[i]]++; 36 sum++; 37 } 38 for (int i = 1; i <= n; ++i) 39 if (cnt[i] >= (sum + 1) / 2) 40 duo = i; 41 int kk = sum - cnt[duo]; 42 if (duo == a[0]) 43 cnt[duo]++; 44 if (duo == -1) 45 printf("%d\n", sum); 46 else 47 printf("%d\n", sum + max(cnt[duo] - 1 - kk, 0)); 48 } 49 50 return 0; 51 }