結果

問題 No.576 E869120 and Rings
ユーザー 明智重蔵明智重蔵
提出日時 2022-12-31 11:10:27
言語 C#
(.NET 8.0.203)
結果
MLE  
(最新)
AC  
(最初)
実行時間 -
コード長 7,344 bytes
コンパイル時間 10,490 ms
コンパイル使用メモリ 145,492 KB
実行使用メモリ 164,512 KB
最終ジャッジ日時 2023-08-17 12:57:02
合計ジャッジ時間 27,354 ms
ジャッジサーバーID
(参考情報)
judge12 / judge13
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 947 ms
52,800 KB
testcase_01 AC 811 ms
50,740 KB
testcase_02 AC 1,036 ms
52,728 KB
testcase_03 AC 1,066 ms
52,752 KB
testcase_04 AC 945 ms
54,724 KB
testcase_05 AC 955 ms
52,716 KB
testcase_06 AC 911 ms
54,540 KB
testcase_07 AC 1,041 ms
54,692 KB
testcase_08 AC 813 ms
52,564 KB
testcase_09 AC 762 ms
55,464 KB
testcase_10 AC 803 ms
55,140 KB
testcase_11 AC 684 ms
54,040 KB
testcase_12 AC 705 ms
53,204 KB
testcase_13 AC 636 ms
56,780 KB
testcase_14 AC 762 ms
52,424 KB
testcase_15 AC 61 ms
39,276 KB
testcase_16 AC 602 ms
72,288 KB
testcase_17 AC 651 ms
53,064 KB
testcase_18 AC 678 ms
53,148 KB
testcase_19 AC 676 ms
52,812 KB
testcase_20 AC 617 ms
52,504 KB
testcase_21 AC 692 ms
52,940 KB
testcase_22 AC 56 ms
28,636 KB
testcase_23 AC 57 ms
28,808 KB
testcase_24 AC 57 ms
28,968 KB
testcase_25 AC 54 ms
28,816 KB
testcase_26 AC 56 ms
28,884 KB
testcase_27 AC 58 ms
28,708 KB
testcase_28 AC 57 ms
28,932 KB
testcase_29 MLE -
権限があれば一括ダウンロードができます
コンパイルメッセージ
  Determining projects to restore...
  Restored /home/judge/data/code/main.csproj (in 172 ms).
.NET 向け Microsoft (R) Build Engine バージョン 17.0.0-preview-21470-01+cb055d28f
Copyright (C) Microsoft Corporation.All rights reserved.

  プレビュー版の .NET を使用しています。https://aka.ms/dotnet-core-preview をご覧ください
  main -> /home/judge/data/code/bin/Release/net6.0/main.dll
  main -> /home/judge/data/code/bin/Release/net6.0/publish/

ソースコード

diff #

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("8 4");
            WillReturn.Add("11101110");
            //0.857142857142857
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("8 4");
            WillReturn.Add("11011001");
            //0.833333333333333
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("10 4");
            WillReturn.Add("1001001001");
            //0.6
        }
        else if (InputPattern == "Input4") {
            return System.IO.File.ReadAllLines(@"D:\CSharp\TestConsole\test_in\in01.txt").ToList();
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    static int mN;
    static int mK;

    static double[] mAArr;

    static void Main()
    {
        //var sw = System.Diagnostics.Stopwatch.StartNew();
        List<string> InputList = GetInputList();
        int[] wkArr = InputList[0].Split(' ').Select(pX => int.Parse(pX)).ToArray();
        mN = wkArr[0];
        mK = wkArr[1];
        mCompareArr = new double[mN * 2];
        mRunSumArr = new double[mN * 2];

        string AStr = InputList[1];
        mAArr = new double[mN];
        bool HasZero = false;
        for (int I = 0; I <= AStr.Length - 1; I++) {
            if (AStr[I] == '0') {
                mAArr[I] = 0D;
                HasZero = true;
            }
            if (AStr[I] == '1') mAArr[I] = 1D;
        }

        // 全て1の場合
        if (HasZero == false) {
            Console.WriteLine(1);
            return;
        }

        // 答えで二分探索
        double L = 0;
        double R = 1;

        while (L + 0.0000001 < R) {
            double Mid = (L + R) / 2;

            bool Result = CanAchieve(Mid);
            if (Result) {
                L = Mid;
            }
            else {
                R = Mid;
            }
        }
        Console.WriteLine(R);
        //Console.WriteLine(sw.Elapsed);
    }

    static double[] mCompareArr;
    static double[] mRunSumArr;

    // NeedAVGを達成できるかを判定
    static bool CanAchieve(double pNeedAVG)
    {
        for (int I = 1; I <= 2; I++) {
            for (int J = 0; J <= mAArr.GetUpperBound(0); J++) {
                mCompareArr[J + mN * (I - 1)] = mAArr[J] - pNeedAVG;
            }
        }
        int UB = mCompareArr.GetUpperBound(0);

        // 累積和を設定する
        for (int I = 0; I <= UB; I++) {
            mRunSumArr[I] = mCompareArr[I];
            if (0 < I) {
                mRunSumArr[I] += mRunSumArr[I - 1];
            }
        }

        var InsDeque = new Deque<int>();

        // 終端を全探索
        bool FirstFlag = true;
        int PrevRangeEnd = -1;

        for (int I = 0; I <= UB; I++) {
            // 長さKの区間を取れなければcontinue
            if (I - mK + 1 < 0) continue;

            // 始点候補のSta
            int RangeSta = I - mN + 1;
            RangeSta = Math.Max(0, RangeSta);

            // 始点候補のEnd
            int RangeEnd = I - mK + 1;

            if (FirstFlag) {
                FirstFlag = false;
            }
            else {
                RangeSta = Math.Max(RangeSta, PrevRangeEnd + 1);
            }

            // 引退処理
            while (InsDeque.Count > 0) {
                int FrontInd = InsDeque[0];
                if (RangeSta <= FrontInd && FrontInd <= RangeEnd == false) {
                    InsDeque.PopFront();
                    continue;
                }
                break;
            }

            for (int J = RangeSta; J <= RangeEnd; J++) {
                // 押し出し処理
                while (InsDeque.Count > 0) {
                    int LastInd = InsDeque[InsDeque.Count - 1];
                    if (mRunSumArr[LastInd] - mCompareArr[LastInd] > mRunSumArr[J] - mCompareArr[J]) {
                        InsDeque.PopBack();
                        continue;
                    }
                    break;
                }
                // 追加処理
                InsDeque.PushBack(J);
            }
            PrevRangeEnd = RangeEnd;

            // 最小値
            double MinVal = mRunSumArr[InsDeque[0]] - mCompareArr[InsDeque[0]];
            if (mRunSumArr[I] - MinVal >= 0) return true;
        }
        return false;
    }
}

#region Deque
internal class Deque<T>
{
    T[] buf;
    int offset, count, capacity;

    internal int Count { get { return count; } }

    internal Deque(int cap) { buf = new T[capacity = cap]; }

    internal Deque() { buf = new T[capacity = 16]; }

    internal T this[int index]
    {
        get { return buf[GetIndex(index)]; }
        set { buf[GetIndex(index)] = value; }
    }

    private int GetIndex(int index)
    {
        if (index >= capacity)
            throw new IndexOutOfRangeException("out of range");
        int ret = index + offset;
        if (ret >= capacity)
            ret -= capacity;
        return ret;
    }

    internal void PushFront(T item)
    {
        if (count == capacity) Extend();
        if (--offset < 0) offset += buf.Length;
        buf[offset] = item;
        count++;
    }

    internal T PopFront()
    {
        if (count == 0)
            throw new InvalidOperationException("collection is empty");
        count--;
        T ret = buf[offset++];
        if (offset >= capacity) offset -= capacity;
        return ret;
    }

    internal void PushBack(T item)
    {
        if (count == capacity) Extend();
        int id = count + offset;
        count++;
        if (id >= capacity) id -= capacity;
        buf[id] = item;
    }

    internal T PopBack()
    {
        if (count == 0)
            throw new InvalidOperationException("collection is empty");
        return buf[GetIndex(--count)];
    }

    internal void Insert(int index, T item)
    {
        if (index > count) throw new IndexOutOfRangeException();
        this.PushFront(item);
        for (int i = 0; i < index; i++)
            this[i] = this[i + 1];
        this[index] = item;
    }

    internal T RemoveAt(int index)
    {
        if (index < 0 || index >= count) throw new IndexOutOfRangeException();
        T ret = this[index];
        for (int i = index; i > 0; i--)
            this[i] = this[i - 1];
        this.PopFront();
        return ret;
    }

    private void Extend()
    {
        T[] newBuffer = new T[capacity << 1];
        if (offset > capacity - count) {
            int len = buf.Length - offset;
            Array.Copy(buf, offset, newBuffer, 0, len);
            Array.Copy(buf, 0, newBuffer, len, count - len);
        }
        else Array.Copy(buf, offset, newBuffer, 0, count);
        buf = newBuffer;
        offset = 0;
        capacity <<= 1;
    }

    internal T[] Items//デバッグ時に中身を調べるためのプロパティ
    {
        get
        {
            T[] a = new T[count];
            for (int i = 0; i < count; i++)
                a[i] = this[i];
            return a;
        }
    }
}
#endregion
0