裏 RjpWiki

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

体積から考える直方体の組み合わせ

2017年12月12日 | ブログラミング

体積から考える直方体の組み合わせ

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

いずれの辺の長さも整数である3つの直方体を考えます。

その直方体の体積の和が与えられたとき、考えられる直方体の組み合わせが何通りあるかを求めてください。
(縦、横、高さを入れ替えたものは一つとカウントします。また、直方体の順番を入れ替えたものも一つとカウントします。)

例えば、体積の和が10のとき、直方体の縦,横,高さは以下の16パターンがあります。

No 一つ目の直方体 二つ目の直方体 三つ目の直方体
 1 1, 1, 1  1, 1, 1  1, 1, 8
 2 1, 1, 1  1, 1, 1  1, 2, 4
 3 1, 1, 1  1, 1, 1  2, 2, 2
 4 1, 1, 1  1, 1, 2  1, 1, 7
 5 1, 1, 1  1, 1, 3  1, 1, 6
 6 1, 1, 1  1, 1, 3  1, 2, 3
 7 1, 1, 1  1, 1, 4  1, 1, 5
 8 1, 1, 1  1, 2, 2  1, 1, 5
 9
 1, 1, 2  1, 1, 2  1, 1, 6
10 1, 1, 2  1, 1, 2  1, 2, 3
11 1, 1, 2  1, 1, 3  1, 1, 5
12 1, 1, 2  1, 1, 4  1, 1, 4
13 1, 1, 2  1, 1, 4  1, 2, 2
14 1, 1, 2  1, 2, 2  1, 2, 2
15 1, 1, 3  1, 1, 3  1, 1, 4
16 1, 1, 3  1, 1, 3  1, 2, 2
標準入力から体積の和が与えられるとき、直方体の組み合わせの数を標準出力に出力してください。
なお、体積の和は300以下の整数とします。

【入出力サンプル】
標準入力
10

標準出力
16

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

R でも結構いいところまで行くが,Java には勝てない

ag = integer(300)

g = function(v) {
  count = 0
  for (i1 in 1:ceiling(v ^ (1 / 3))) {
    for (i2 in i1:v) {
      if (i1 * i2 > v) {
        break
      }
      i3 = v / (i1 * i2)
      if (i3 < i2) {
        break
      } else if (i3 == floor(i3)) {
        count = count + 1
        ag[count] = (i1 * 1000 + i2) * 1000 + i3
      }
    }
  }
  ag[1:count]
}

tbl = vector("list", 300)
for (i in 1:300) {
  tbl[[i]] = g(i)
}

f = function(v) {
  ah = matrix(0, 3000, 3)
  count = 0
  for (i1 in 1:ceiling(v / 3)) {
    lst1 = tbl[[i1]]
    for (i2 in i1:v) {
      if (i1 + i2 > v) {
        break
      }
      i3 = v - i1 - i2
      if (i3 < i2) {
        break
      }
      lst2 = tbl[[i2]]
      lst3 = tbl[[i3]]
      l1 = length(lst1)
      l2 = length(lst2)
      l3 = length(lst3)
      count2 = 0
      for (j1 in 1:l1) {
        for (j2 in 1:l2) {
          for (j3 in 1:l3) {
            mx = max(lst1[j1], lst2[j2], lst3[j3])
            mn = min(lst1[j1], lst2[j2], lst3[j3])
            me = lst1[j1] + lst2[j2] + lst3[j3] - mx - mn
            count2 = count2 + 1
            ah[count2, ] = c(mn, me, mx)
          }
        }
      }
      count = count + nrow(unique(ah[1:count2, , drop = FALSE]))
    }
  }
  cat(count)
}

# f(scan(file("stdin", "r")))

system.time(f(9)) # 11
system.time(f(10)) # 16
system.time(f(20)) # 133
system.time(f(64)) # 4563
system.time(f(100)) # 17251
system.time(f(300)) # 438379

コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« 半径が同じ円を重ならないよ... | トップ | 「ペア・ドロップ」問題 »
最新の画像もっと見る

コメントを投稿

ブログラミング」カテゴリの最新記事