結果

問題 No.3252 Constrained Moving
コンテスト
ユーザー aaa aa
提出日時 2025-12-09 21:42:18
言語 C#
(.NET 8.0.404)
結果
AC  
実行時間 285 ms / 2,000 ms
コード長 2,038 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 8,522 ms
コンパイル使用メモリ 170,716 KB
実行使用メモリ 221,100 KB
最終ジャッジ日時 2025-12-09 21:42:40
合計ジャッジ時間 18,611 ms
ジャッジサーバーID
(参考情報)
judge1 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 30
権限があれば一括ダウンロードができます
コンパイルメッセージ
  復元対象のプロジェクトを決定しています...
  /home/judge/data/code/main.csproj を復元しました (111 ミリ秒)。
  main -> /home/judge/data/code/bin/Release/net8.0/main.dll
  main -> /home/judge/data/code/bin/Release/net8.0/publish/

ソースコード

diff #
raw source code

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var inp = Console.ReadLine().Split();
        int N = int.Parse(inp[0]);
        int S = int.Parse(inp[1]) - 1;
        int T = int.Parse(inp[2]) - 1;
        long K = long.Parse(inp[3]);

        var A = Array.ConvertAll(Console.ReadLine().Split(), long.Parse);

        // (値, index)をまとめてソート
        var items = new List<(long val, int idx)>();
        for (int i = 0; i < N; i++) items.Add((A[i], i));
        items.Sort((x, y) => x.val.CompareTo(y.val));

        // 未訪問集合を値昇順に保持(実体は List+pointer で十分)
        var alive = new LinkedList<(long val, int idx)>(items);

        var visited = new bool[N];
        var dist = new int[N];
        var q = new Queue<int>();

        visited[S] = true;
        q.Enqueue(S);

        // S の項目を alive から除去
        var node = alive.First;
        while (node != null)
        {
            if (node.Value.idx == S)
            {
                var tmp = node;
                node = node.Next;
                alive.Remove(tmp);
                break;
            }
            node = node.Next;
        }

        while (q.Count > 0)
        {
            int u = q.Dequeue();

            if (u == T)
            {
                Console.WriteLine(dist[u]);
                return;
            }

            long limit = K - A[u];

            // alive の先頭から limit 以下のものを全て取り出す
            var cur = alive.First;
            while (cur != null && cur.Value.val <= limit)
            {
                int v = cur.Value.idx;

                if (!visited[v])
                {
                    visited[v] = true;
                    dist[v] = dist[u] + 1;
                    q.Enqueue(v);
                }

                var tmp = cur;
                cur = cur.Next;
                alive.Remove(tmp);
            }
        }

        Console.WriteLine(-1);
    }
}
0