裏 RjpWiki

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

取られたら取り返す!

2017年05月09日 | ブログラミング

取られたら取り返す!

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

設問

卓球では11点先取、バレーボールでは25点先取で1セットを取るようなルールがあります。
ただ、この得点よりも1点少ない得点以上の得点で同点となると「デュース」と呼ばれることがあり、その後は2点差を付けるまで続けられます。
(卓球やバドミントンにはデュースという言葉はありませんが、同様に進められます。)

A と B がn 点先取の試合を行ったとき、それぞれの点数が a 対 b になるまでの点数の推移を考えます。
例えば、n = 3, a = 4, b = 2 のとき、点数の推移は以下の6通りがあります。
(下記の記号は点数を取った側を表すものとします。)

(1) A -> A -> B -> B -> A -> A
(2) A -> B -> A -> B -> A -> A
(3) A -> B -> B -> A -> A -> A
(4) B -> A -> A -> B -> A -> A
(5) B -> A -> B -> A -> A -> A
(6) B -> B -> A -> A -> A -> A

このとき、以下のように点数が推移することはありません。
(途中で3点を先取してしまい、セットが終了するため)
A -> A -> B -> A -> B -> A

標準入力から n, a, b がスペース区切りで与えられるとき、点数の推移が何通りあるかを求め、標準出力に出力してください。
なお、n, a, b はいずれも25以下の正の整数とします。

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

標準出力
6

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

例によって,サイズの小さい場合について,馬鹿正直に計算するプログラムを書き,結果から規則性を見いだす。

n = 6 の場合については下図のようになる。



水色の部分は i, j > 1 において,x[i, j] = x[i-1, j] + x[i, j-1]
黄色の部分は近隣のコピー(コピーの順番に注意)

ということで,一般的には

f = function(n, a, b) {
    x = matrix(0, 28, 28) # 計算途中で添え字が溢れないように +2
    for (i in 1:n-1) {
        for (j in 1:n-1) {
            x[i+1, j+1] = choose(i+j, i)
        }
    }
    x[n+1, 1:n] = x[1:n, n+1] = x[n, 1:n]
    for (i in n:26) {
        x[i, i+1:2] = x[i+1:2, i] = x[i, i] = x[i-1, i] + x[i, i-1]

    }
    cat(x[a+1, b+1])
}
# s = scan(file("stdin", "r"))
# f(s[1], s[2], s[3])

f(3, 4, 2) # 6
f(10, 9, 8) # 24310
f(15, 0, 14) # 1
f(15, 17, 20) # 0
f(11, 25, 24) # 3027042304



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

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

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