Google Code Jam万里の長城問題のより速い解決策はありますか
次のGoogle Code Jamラウンド1Cの質問を検討してください。 万里の長城は無限の線から始まり、すべての場所の高さはです。000 いくつかの部族NNN、N≤1000N≤1000N \le 1000は、開始日DDD、開始強度SSS、開始西座標WWW、開始東座標Eのパラメーターに従って、壁を壁に攻撃します。EEE。この最初の攻撃は、DDD日、範囲[W,E][W,E][W,E]、強度SSSます。[W、E]内に[W,E][W,E][W,E]高さ<Sの万里の長城の部分がある場合<S<S< S、攻撃は成功し、その日の終わりに、[W,E][W,E][W,E]の高さ<S<S< Sは高さになるSSS(またはその日、他の攻撃が同じセグメントに強度ヒットした場合)S′>SS′>SS' > S 各部族は退却する前に最大攻撃を実行し、各攻撃はその前の攻撃から繰り返し決定されます。すべての部族は、いくつか持っている、、および攻撃の彼らの順序を決定します。お待ちしております攻撃の間に日を、彼らは攻撃範囲に移動します各攻撃(ネガティブ=西、正の単位を=東)、ただし、範囲のサイズは同じままであり、各攻撃の後、その強さも一定の値で増加/減少します。100010001000δDδD\delta_DδXδX\delta_XδSδS\delta_SδD≥1δD≥1\delta_D \ge 1δXδX\delta_X 問題の目標は、攻撃している部族の完全な説明が与えられれば、攻撃が成功する数を決定することです。 約20秒で動作するソリューションをコーディングできました。実装したソリューションにはO(AlogA+(A+X)logX)O(AlogA+(A+X)logX)O(A\log A + (A+X)\log X)時間かかります。ここで、A=A=A =攻撃の総数シミュレーション(最大100000010000001000000)、およびX=X=X =攻撃範囲の一意のエッジポイントの総数(最大200000020000002000000)。 高いレベルで、私のソリューション: すべての部族情報を読み込みます 攻撃範囲のすべての一意のXXX座標を計算しますO(A)O(A)O(A) 最小の高さの値を追跡するXXX範囲上の遅延更新されたバイナリツリーとして壁を表します。リーフは、間に何もない2つのXXX座標のスパンであり、すべての親ノードは、子によってカバーされる連続的な間隔を表します。- O(XlogX)O(XlogX)O(X \log X) すべての部族が実行するすべての攻撃を生成し、日ごとにソートしますO(AlogA)O(AlogA)O(A \log A) 各攻撃について、成功するかどうかを確認します(logXlogX\log Xクエリ時間)。日が変わったら、未処理のすべての成功した攻撃をループし、それに応じてウォールを更新します(logXlogX\log X各攻撃の\ log X更新時間)。- O(AlogX)O(AlogX)O(A\log X) 私の質問はこれです:よりも良い方法はありか?おそらく、部族の連続攻撃の線形性を利用する戦略的な方法はありますか?20秒は、意図したソリューションには長すぎると感じます(ただし、Javaはそのせいかもしれません)。O(AlogA+(A+X)logX)O(AlogA+(A+X)logX)O(A\log A + (A+X)\log X)