結果

問題 No.5008 [Cherry Alpha] Discrete Pendulum with Air Resistance
ユーザー tomeruntomerun
提出日時 2022-10-14 22:43:48
言語 Crystal
(1.11.2)
結果
WA  
実行時間 -
コード長 3,400 bytes
コンパイル時間 21,913 ms
実行使用メモリ 6,956 KB
スコア 0
最終ジャッジ日時 2022-10-14 22:45:56
合計ジャッジ時間 126,850 ms
ジャッジサーバーID
(参考情報)
judge14 / judge11
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 WA -
testcase_01 WA -
testcase_02 WA -
testcase_03 WA -
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 WA -
testcase_08 WA -
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
testcase_20 WA -
testcase_21 WA -
testcase_22 WA -
testcase_23 WA -
testcase_24 WA -
testcase_25 WA -
testcase_26 WA -
testcase_27 WA -
testcase_28 WA -
testcase_29 WA -
testcase_30 WA -
testcase_31 WA -
testcase_32 WA -
testcase_33 WA -
testcase_34 WA -
testcase_35 WA -
testcase_36 WA -
testcase_37 WA -
testcase_38 WA -
testcase_39 WA -
testcase_40 WA -
testcase_41 WA -
testcase_42 WA -
testcase_43 WA -
testcase_44 WA -
testcase_45 WA -
testcase_46 WA -
testcase_47 WA -
testcase_48 WA -
testcase_49 WA -
権限があれば一括ダウンロードができます

ソースコード

diff #

START_TIME = Time.utc.to_unix_ms
TL         = 1900
N          =   50
K          =   50
RND        = Random.new(2)

macro debug(msg)
  {% if flag?(:local) %}
    STDERR.puts({{msg}})
  {% end %}
end

class Result
  getter :score, :b, :m, :e

  def initialize(@score : Int64, @b : Array(Int32), @m : Array(Int32), @e : Array(Int32))
  end
end

class Solver
  @ts : Array(Int32)
  @us : Array(Int32)

  def initialize
    read_line
    @ts = read_line.split.map(&.to_i)
    @us = read_line.split.map(&.to_i)
    @b = Array(Int32).new(N) { RND.rand(2) + 1 }
    @m = Array(Int32).new(N) { RND.rand(2) + 1 }
    @e = Array(Int32).new(N) { RND.rand(2) + 1 }
    @pos_200 = Array(Int32).new(N, 0)
    @dir_200 = Array(Int32).new(N, 1)
    N.times do |i|
      @pos_200[i], @dir_200[i] = sim_200(@b[i], @m[i], @e[i])
    end
    @pos_ts = Array(Array(Int32)).new(N) { Array.new(K, 0) }
    @pos_us = Array(Array(Int32)).new(N) { Array.new(K, 0) }
    N.times do |i|
      sim_k(i)
    end
  end

  def sim_200(b, m, e)
    p = 0
    d = 1
    a = b
    200.times do
      p += d
      if p == a * d
        d *= -1
        a = {m, a - e}.max
      end
    end
    return p, d
  end

  def sim_k(i)
    K.times do |j|
      t = (@ts[j] - 200) % (@m[i] * 4)
      p = @pos_200[i]
      d = @dir_200[i]
      t.times do
        p += d
        if p == @m[i] * d
          d *= -1
        end
      end
      @pos_ts[i][j] = p

      t = (@us[j] - 200) % (@m[i] * 4)
      p = @pos_200[i]
      d = @dir_200[i]
      t.times do
        p += d
        if p == @m[i] * d
          d *= -1
        end
      end
      @pos_us[i][j] = p
    end
  end

  def solve
    best_res = Result.new(calc_score(), @b.dup, @m.dup, @e.dup)
    buf_pos_ts = Array.new(K, 0)
    buf_pos_us = Array.new(K, 0)
    turn = 0
    while true
      turn += 1
      if (turn & 0xFF) == 0
        if Time.utc.to_unix_ms - START_TIME > TL
          debug("total_turn:#{turn} score:#{best_res.score}")
          break
        end
      end
      ch_i = RND.rand(N)
      nb = RND.rand(6) + 1
      nm = RND.rand(4) + 1
      ne = RND.rand(4) + 1
      old = {@pos_200[ch_i], @dir_200[ch_i]}
      @pos_200[ch_i], @dir_200[ch_i] = sim_200(nb, nm, ne)
      K.times do |i|
        buf_pos_ts[i] = @pos_ts[ch_i][i]
        buf_pos_us[i] = @pos_us[ch_i][i]
      end
      sim_k(ch_i)
      score = calc_score()
      if best_res.score < score
        debug("score:#{score} at turn #{turn}")
        best_res = Result.new(score, @b.dup, @m.dup, @e.dup)
      else
        @pos_200[ch_i] = old[0]
        @dir_200[ch_i] = old[1]
        K.times do |i|
          @pos_ts[ch_i][i] = buf_pos_ts[i]
          @pos_us[ch_i][i] = buf_pos_us[i]
        end
      end
    end
    return best_res
  end

  def calc_score
    sum0 = 0i64
    sum1 = 0i64
    K.times do |i|
      sum = 0.0
      N.times do |j|
        j.times do |k|
          sum += (@pos_ts[j][i] - @pos_ts[k][i]).abs / (@b[j] + @b[k])
        end
      end
      sum0 += (sum * 20_000_000 / (N * (N - 1))).round.to_i
      min = 1 << 20
      max = -(1 << 20)
      N.times do |j|
        min = {min, @pos_us[j][i]}.min
        max = {max, @pos_us[j][i]}.max
      end
      sum1 += (10_000_000 / (((max - min) * 0.05) ** 0.5 + 1)).round.to_i
    end
    return sum0 * sum1
  end
end

solver = Solver.new
res = solver.solve
N.times do |i|
  puts "#{res.b[i]} #{res.m[i]} #{res.e[i]}"
end
0