Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで最大人口となる年を求めるプログラムの書き方

問題の概要

ここでは、birth(出生年)と death(死亡年)の2列を持つ表を考えます。各行は i 番目の人物の出生年と死亡年を表しています。ある年 y の「人口」とは、その年に生存している人数のことです。i 番目の人物は、y が閉区間 [birth_i, death_i − 1] に含まれる場合に、年 y の人口としてカウントされます(死亡した当年は数えません)。この条件のもとで、人口が最大となる年のうち、最も早い年を求めるのが目的です。

入力例

BirthDeath
19702010
19602020
19401970

この場合、出力は 1960 になります。1960年には2人(1960年生まれ〜2020年没の人と、1940年生まれ〜1970年没の人)が生存しており、これが最大人口だからです。1970年にも2人が生存しますが、より早い年である1960年が答えとなります。

解き方のアプローチ

この問題を解くためには、以下の手順に従います。

  • d := キーが存在しない場合に 0 を返すマップ(defaultdict)を用意する

  • res := 初期値として [2051, 0] を持つリストを用意する(2051年より後は対象外と仮定)

  • matrix 内の各 (YOB: 出生年, YOD: 死亡年) のペアについて処理を行う

    • range(YOB, YOD) の各年 year に対して次を実行する

      • d[year] := d[year] + 1(その年の人口を1増やす)

      • d[year] >= res[1](現在の最大人口以上)である場合

        • d[year] > res[1](最大人口を更新する)ならば

          • res := [year, d[year]] を設定する

        • そうでなければ(同じ人口だが別の年の場合)

          • res := [min(year, res[0]), res[1]](より早い年を採用する)

  • 最後に res[0](最大人口の最も早い年)を返す

それでは、理解を深めるために実際の実装を見てみましょう。

実装例(Python)

from collections import defaultdict
def solve(matrix):
    d = defaultdict(int)
    res = [2051, 0]
    for YOB, YOD in matrix:
        for year in range(YOB, YOD):
            d[year] += 1
            if d[year] >= res[1]:
                if d[year] > res[1]:
                    res = [year, d[year]]
                else:
                    res = [min(year, res[0]), res[1]]
    return res[0]
matrix = [[1970,2010],[1960,2020],[1940,1970]]
print(solve(matrix))

入力

[[1970,2010],[1960,2020],[1940,1970]]

出力

1960

コードのポイント

この実装では、collections.defaultdict(int) を使うことで、まだキーが存在しない年に対しても自動的に初期値 0 が設定され、シンプルに人口カウントを加算できます。また、死亡年そのものは範囲に含めないよう range(YOB, YOD) としている点が重要です。計算量は人物数を n、寿命の長さを L とすると O(n × L) となり、差分配法(imos法)を使えば O(n + 年幅) まで高速化することも可能です。

  1. Pythonで制約付きの建物の最大高さを求めるプログラム

    問題の概要整数 n と制約リスト restrictions が与えられたとします。私たちは都市に n 棟の新しい建物を一列に建てようとしていますが、高さに関するいくつかの制限があります。建物には左から順に 1 から n までの番号が付けられており、各制約は restrictions[i] = (id_i, max_height_i) の形式で表され、「id_i 番の建物の高さは max_height_i 以下でなければならない」ことを意味します。建物の高さに関する都市の規則は以下のとおりです。各建物の高さは 0 以上でなければなりません。1 番の建物(最初の建物)の高さは必ず 0 です。隣接す

  2. Pythonで最大の成功確率を持つパスを見つけるプログラムの実装方法

    問題の概要 n 個のノード(ノードには 0 から順に番号が振られています)からなる無向重み付きグラフを考えます。このグラフは辺リスト(edge list)として入力され、各辺 e には「その辺を通過する際の成功確率」probability[e] が割り当てられています。さらに、開始ノード(start)と終了ノード(end)も与えられます。 求めたいのは、start から end へ移動するときに成功確率が最大となる経路であり、答えとしてその成功確率を返します。経路がひとつも存在しない場合は 0 を返してください。 たとえば、次のような入力が与えられたとします。 この場合の出力は 0.25