単調増加で単調減少な数
2017年1月13日(金)10:00AMが締め切りなので,その 1 分後に投稿されるように予約
【概要】
たとえば,179 のような数のことを「10 進数で狭義単調増加な数」と呼ぶことにします。
つまり,各桁を見ると狭義単調増加列になっています。
逆に,8631 のような数のことを「10 進数で狭義単調減少な数」と呼ぶことにします。
つまり,各桁を見ると狭義単調減少列になっています。
さて,a 進数で狭義単調増加,b 進数で狭義単調減少な数のうち,もっとも大きな数を求めるプログラムを書いてください。
【入出力】
入力は
5 6
こんな感じで標準入力から来ます。
スペース区切りで2つの10進数が並んでいます。
スペースの前が先程の a,つまりa進数で表記すると狭義単調増加になります。
スペースの後は先程の b,つまりb進数で表記すると狭義単調減少になります。
出力は,条件を満たす値を 10 進数で。先ほどの入力なら,19 を出力すると正解です。
【例】
入力 出力 a進数 b進数
5 6 19 34 31
6 11 101 245 92
4 3 7 13 21
【補足】
• 不正な入力に対処する必要はありません。
• 長さ 1 でも狭義単調増加列になります。
• a も b も,2 以上 16 以下です。
==========================
bc = function(p) { # 要素の組み合わせを行列として求める
retval = matrix(0, nrow = 2^p, ncol = p)
for (n in 1:p) {
retval[, n] = rep(c(rep(0, (2^p/2^n)), rep(1, (2^p/2^n))), length = 2^p)
}
retval
}
is.ok = function(u, b) { # 10 進数の u が,「「b 進数で狭義単調減少な数」か
v = NULL
repeat {
v = c(v, u %% b)
u = u %/% b
if (u == 0) break
}
all(diff(v) > 0)
}
is.ok = function(u, b) { # 順次判定すれば,効率がよいので,こちらを使う
prev = u %% b
u = u %/% b
repeat {
if (u == 0) {
return(TRUE)
}
v = u %% b
if (prev >= v) { # 狭義減少になっていない桁があると FALSE
return(FALSE)
}
u = u %/% b
prev = v
}
}
f = function(a, b) {
mx.b = sum((b-1):1 * b ^ (0:(b-2))) # 「b 進数で狭義単調減少な数」の最大値
w = a ^ (0:(a-2)) # a 進数の各桁の重み(要素1が最下位桁であるように逆順に保存)
mx = 0 # 求める数(最大値)
for (least in (a-1):1) { # 「a 進数で狭義単調増加な数」
x = least:1 # 最下位桁が least,最上位桁が 1
if (length(x) == 1) {
y = 1
} else { # 可能なすべての狭義単調増加な数の各桁
y = apply(cbind(1, bc(least-1)), 1, function(i) x[i==1])
}
for (i in 1:length(y)) {
z = y[[i]]
u = sum(z * w[1:length(z)]) # 10 進数に変換
if (length(z) == 1 && u > mx && is.ok(u, b)) { #「b 進数で狭義単調減少な数」か
mx = u # 今までで一番大きければ記録
} else if (mx.b >= u && u > mx && is.ok(u, b)) {
mx = u
}
}
}
cat(mx) # 結果を表示
}
system.time(f(5, 6)) # 19
system.time(f(15, 16)) # 15571062
system.time(f(13, 16)) # 16558437
system.time(f(2, 16)) # 1
system.time(f(2, 2)) # 1
system.time(f(3, 2)) # 2
system.time(f(7, 11)) # 1266
system.time(f(11, 7)) # 2276
system.time(f(11, 10)) # 3210 7.252 sec.
system.time(f(16, 2)) # 2
system.time(f(16, 15)) # 35806
system.time(f(16, 16)) # 15
system.time(f(16, 13)) # 363743