ダイヤルロックを解除して!
締め切りが 2017/04/18 10:00 AM なので,その 1 分後に投稿されるように予約
設問
以下の図のようなダイヤル式のロックが付いたポストがあります。
このロックを解除するには、ダイヤルを左右交互に回転し、特定の m 桁の番号を作るとポストを開けられます。
なお、最初はダイヤルの位置が「0」にセットされているものとし、左回転から開始します。
(番号は「0」以外から始まり、同じ番号が続くことはありません。) これ重要(見逃して,ドツボに入った)
例えば、m = 3 で「528」という番号の場合、「5」まで左に回し、次に「2」まで右に回し、最後に「8」まで左に回します。
このときに動いた目盛りの数 n を考えます。
上記の「528」の場合、図のように n = 5 + 3 + 6 = 14 となります。
このポストを開けるとき、 m と n は覚えていたのですが、元の番号を忘れてしまいました。
そこで、このポストで m と n の数から番号を推測しようと考えました。
標準入力から m と n がスペース区切りで与えられたとき、考えられる番号が何通りあるかを求め、標準出力に出力してください。
なお、m と n は 0 < m < n < 50 を満たす整数とします。
例えば、 m = 3, n = 6 のとき、以下の10通りがあります。
「104」「178」「180」「192」「202」「214」「290」「312」「324」「434」
【入出力サンプル】
標準入力
3 6
標準出力
10
====================================
いつも通りの方針に従う。すなわち,m の小さい場合について解を求め,規則性を探る。
f = function(m) {
distribution = integer(9*m)
for (i in (10^(m-1)):(10^m - 1)) { # m 桁の数が対象
s = as.integer(unlist(strsplit(sprintf("%0*d", m+1, i), "")))
count = 0
for (k in 1:m) {
if (s[k] == s[k + 1]) { # 「同じ数字が連続することはない」ことから
count = 0
break
} else if (k%%2 == 1) {
count = count + (s[k]-s[k + 1]) %% 10 # 左回り
} else {
count = count + (s[k + 1]-s[k]) %% 10# 右回り
}
}
if (count != 0) {
distribution[count] = distribution[count] + 1
}
}
distribution
}
> f(1)
[1] 1 1 1 1 1 1 1 1 1
> f(2)
[1] 0 1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1
> f(3)
[1] 0 0 1 3 6 10 15 21 28 36 45 52 57 60 61 60 57 52 45 36 28 21 15 10 6 3 1
> f(4)
[1] 0 0 0 1 4 10 20 35 56 84 120 165 216 270 324 375 420 456 480 489 480 456 420 375 324 270 216 165
[29] 120 84 56 35 20 10 4 1
> f(5)
[1] 0 0 0 0 1 5 15 35 70 126 210 330 495 710 976 1290 1645 2030 2430 2826 3195 3510
[23] 3750 3900 3951 3900 3750 3510 3195 2826 2430 2030 1645 1290 976 710 495 330 210 126 70 35 15 5
[45] 1
下図のようになっている。
以下略
m=3 の列は,m=2の列の (1,2,3,4,...,3,2,1) を 1 要素ずつずらして 9 回足す。
この規則をプログラム化して,大きな m, n のときの解を求める。
f = function(m, n) {
a = rep(1, 9)
for (i in 2:m) {
b = numeric(9*i)
for (j in 1:9) {
b[seq_along(a)+j] = b[seq_along(a)+j] + a
}
a = b
}
a[n]
}
f(3, 6) # 10
f(4, 10) # 84
f(5, 20) # 2826
f(10, 30) # 8337880
f(40, 49) # 1677106600
最新の画像[もっと見る]
-
算額(その2059) 2時間前
-
算額(その2057) 5時間前
-
算額(その2056) 20時間前
-
算額(その2055) 20時間前
-
算額(その2054) 1日前
-
算額(その2053) 1日前
-
算額(その2052) 1日前
-
算額(その2051) 1日前
-
算額(その2051) 1日前
-
算額(その2050) 2日前
※コメント投稿者のブログIDはブログ作成者のみに通知されます