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