取られたら取り返す!
締め切りが 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