• Aiiage Camp Day4 C KTV


    题意

      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
    ", sum);
    46         else
    47             printf("%d
    ", sum + max(cnt[duo] - 1 - kk, 0));
    48     }
    49 
    50     return 0;
    51 }
  • 相关阅读:
    hdu 4963(中途相遇法)
    UVALive 6869(后缀数组)
    AC自动机小结
    poj 2409+2154+2888(Burnside定理)
    HUST 1569(Burnside定理+容斥+数位dp+矩阵快速幂)
    bunoj 34990(hash)
    CSU 1506(最小费用最大流)
    CF 514C(hash)
    lightoj 1297(三分)
    lightoj 1179(线段树)
  • 原文地址:https://www.cnblogs.com/aseer/p/8461414.html
Copyright © 2020-2023  润新知