AtCoderのARC    次のARCの問題へ    前のARCの問題へ

ARC179-A Partition


問題へのリンク


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 1");
            WillReturn.Add("-1 2 -3 4");
            //Yes
            //-3 -1 2 4
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("4 -1");
            WillReturn.Add("1 -2 3 -4");
            //No
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("10 1000000000");
            WillReturn.Add("-1000000000 -1000000000 -1000000000 -1000000000 -1000000000 1000000000 1000000000 1000000000 1000000000 1000000000");
            //Yes
            //-1000000000 -1000000000 -1000000000 -1000000000 -1000000000 1000000000 1000000000 1000000000 1000000000 1000000000
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    static void Main()
    {
        List<string> InputList = GetInputList();
        long[] wkArr = InputList[0].Split(' ').Select(pX => long.Parse(pX)).ToArray();
        long K = wkArr[1];

        long[] AArr = InputList[1].Split(' ').Select(pX => long.Parse(pX)).ToArray();
        Array.Sort(AArr);

        var InsLinkedList = new LinkedList<long>(AArr);

        bool IsLowerK = true; // K未満か?

        var AnswerList = new List<long>();
        long CurrSum = 0;
        while (InsLinkedList.Count > 0) {
            if (CurrSum >= K) {
                IsLowerK = false;
            }

            if (IsLowerK) {
                long MinVal = InsLinkedList.First.Value;
                InsLinkedList.RemoveFirst();
                CurrSum += MinVal;
                AnswerList.Add(MinVal);
            }
            else {
                long MaxVal = InsLinkedList.Last.Value;
                InsLinkedList.RemoveLast();
                CurrSum += MaxVal;

                if (CurrSum < K) {
                    Console.WriteLine("No");
                    return;
                }
                AnswerList.Add(MaxVal);
            }
        }
        Console.WriteLine("Yes");
        Console.WriteLine(LongEnumJoin(" ", AnswerList));
    }

    // セパレータとLong型の列挙を引数として、結合したstringを返す
    static string LongEnumJoin(string pSeparater, IEnumerable<long> pEnum)
    {
        string[] StrArr = Array.ConvertAll(pEnum.ToArray(), pX => pX.ToString());
        return string.Join(pSeparater, StrArr);
    }
}


解説

累積和がK未満なら、使える値で最小値を使う
累積和がK以上なら、使える値で最大値を使う
として、解けます。

最小値または最大値を取り出すデータ構造は、
AVL木を使ってもいいですが、
LinkedListに昇順にデータをInsertしておいてもいいです。