裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

スイッチを反転しても同じ数だけ点灯する?

2017年11月07日 | ブログラミング

スイッチを反転しても同じ数だけ点灯する?

締め切りが 2017/11/07 10:00 AM なので,その 1 分後に投稿されるように予約

設問

家庭に必ずある分電盤。その中にはブレーカーがあり、家庭内の電気スイッチやコンセントなどにつながっています。
ここでは、1つのブレーカーが2つのスイッチにつながっているものとします。
また、それぞれのスイッチに対して電球が1つずつ付いています。
スイッチをONにしても、そのスイッチにつながるブレーカーでONになっていないと電球は点灯しません。
もちろん、ブレーカーがONになっていても、スイッチがONになっていないと電球は点灯しません。

今、m 個のブレーカーがあり、n 個の電球が点灯しています。
ここで、すべてのスイッチを反転させたとき、点灯している電球の数が同じでした。
(あくまでもスイッチ部分の反転のみで、ブレーカーを触ることはありません。)
このようなブレーカー、スイッチの状態が何通りあるか求めます。


例えば、m = 2, n = 1 のとき、以下のような16通りがあります。
(色が付いている部分が点灯している部分)

同様に、m = 3, n = 2 のときは72通りがあります。
標準入力から m, n がスペース区切りで与えられたとき、上記のような状態が何通りあるか求め、
そのパターン数を標準出力に出力してください。
なお、m, n はともに20以下の正の整数とします。


【入出力サンプル】
標準入力
2 1

標準出力
16

=======================================================

m, n の小さい場合に対するプログラム(最後尾に記載)により,下図の配列 b を得る。

配列 b の対角成分 b[n, n] は choose(2*n, n)
n 行において b[n, m+1] = b[n, m] * a[n, m ]
配列 a は,分数表示すると,規則性があることがわかる。
a[n, m ] = 4*(m+1)/(m-n+1)

これをプログラム化する(面倒くさいので,m = n = 20 までの全てについて表を作る)。

f = function(M, N) {
    options(scipen=100)
    mx = 20
    b = a = matrix(0, mx, mx)
    for (m in 1:mx) {
        for (n in m:1) {
            a[n, m] = 4*(m+1)/(m-n+1)
        }
    }
    for (n in 1:mx) {
        b[n, n] = x = choose(2*n, n)
        if (n < mx) {
            for (m in n:(mx-1)) {
                b[n, m+1] = b[n, m]*a[n, m]
            }
        }
    }
    cat(b[N, M])
}

f(2, 1) # 16
f(3, 2) # 72
f(10, 5) # 65028096
f(16, 15) # 9927521280
f(20, 20) # 137846528820

小規模な配列 b を求めるプログラム

f = function(m, n) {
    library(e1071)
    a = bincombinations(3*m)
    count = 0
    for (j in 1:nrow(a)) {
        N1 = N2 = 0
        for (i in 1:m) {
            N1 = N1+sum(a[j, i]*a[j, m+2*i-1:0])
            N2 = N2+sum(a[j, i]*(1-a[j, m+2*i-1:0]))
        }
        count = count + (N1 == N2 && N1 == n)
    }
    count
}

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PVアクセスランキング にほんブログ村

PVアクセスランキング にほんブログ村