AtCoderのABC    次のABCの問題へ    前のABCの問題へ

ABC111-C /\/\/\/


問題へのリンク


C#のソース

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static string InputPattern = "InputX";

    static List<string> GetInputList()
    {
        var WillReturn = new List<string>();

        if (InputPattern == "Input1") {
            WillReturn.Add("4");
            WillReturn.Add("3 1 3 2");
            //1
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("6");
            WillReturn.Add("105 119 105 119 105 119");
            //0
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("4");
            WillReturn.Add("1 1 1 1");
            //2
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    static void Main()
    {
        List<string> InputList = GetInputList();

        int[] VArr = InputList[1].Split(' ').Select(pX => int.Parse(pX)).ToArray();

        // 処理01 偶数要素と奇数要素のそれぞれのListを作成
        var EvenList = new List<int>();
        var OddList = new List<int>();
        for (int I = 0; I <= VArr.GetUpperBound(0); I++) {
            if (I % 2 == 0) {
                EvenList.Add(VArr[I]);
            }
            else {
                OddList.Add(VArr[I]);
            }
        }

        // 処理02 偶数要素と奇数要素の最頻値と、その次の最頻値を求める
        var EvenModeTmp = EvenList.GroupBy(pX => pX).Select(pX => new { Key = pX.Key, Cnt = pX.Count() });
        var OddModeTmp = OddList.GroupBy(pX => pX).Select(pX => new { Key = pX.Key, Cnt = pX.Count() });

        var EvenModeArr = EvenModeTmp.OrderByDescending(pX => pX.Cnt).Take(2).ToArray();
        var OddModeArr = OddModeTmp.OrderByDescending(pX => pX.Cnt).Take(2).ToArray();

        // 場合01 最頻値が異なる場合
        if (EvenModeArr[0].Key != OddModeArr[0].Key) {
            long Answer = 0;
            Answer += EvenList.Count - EvenModeArr[0].Cnt;
            Answer += OddList.Count - OddModeArr[0].Cnt;
            Console.WriteLine(Answer);
        }
        else {
            // その次の最頻値の要素数を求めておく
            int EvenNextModeCnt = 0;
            if (EvenModeArr.Length == 2) {
                EvenNextModeCnt = EvenModeArr[1].Cnt;
            }
            int OddNextModeCnt = 0;
            if (OddModeArr.Length == 2) {
                OddNextModeCnt = OddModeArr[1].Cnt;
            }

            // 場合02 最頻値が異なり、偶数要素は最頻値で統一、奇数要素はその次の最頻値で統一
            long AnswerKouho1 = 0;
            AnswerKouho1 += EvenList.Count - EvenModeArr[0].Cnt;
            AnswerKouho1 += OddList.Count - OddNextModeCnt;

            // 場合03 最頻値が異なり、奇数要素は最頻値で統一、偶数要素はその次の最頻値で統一
            long AnswerKouho2 = 0;
            AnswerKouho2 += EvenList.Count - EvenNextModeCnt;
            AnswerKouho2 += OddList.Count - OddModeArr[0].Cnt;

            Console.WriteLine(Math.Min(AnswerKouho1, AnswerKouho2));
        }
    }
}


解説

場合01 偶数要素と奇数要素で最頻値が異なる場合
最頻値にするのが最適

場合02 偶数要素と奇数要素で最頻値が同じ場合
下記の2通りで良いほうが解

●偶数要素は最頻値にする。奇数要素は次の最頻値にする。
●奇数要素は最頻値にする。偶数要素は次の最頻値にする。