0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

アルゴリズムでよく使う手法(Ruby)

Last updated at Posted at 2022-09-19

アルゴリズムでよく使う手法まとめ

paizaでアルゴリズムの練習問題でよく使い、よくつまずくポイントを残します。

向きについて

マスを進んでいく問題で向きを変えながら一マスずつ進む問題での向き判定

# 左から上、右、下、左
move = [[-1, 0], [0, 1], [1, 0], [0, -1]]

# 向き
now = 0

# 初期位置
y, x = [3, 3]

# 向きによってy, xを変える
# 向きの値を4で割り、その値によってmoveに入っている変化する値を取得できる。
ny = y + move[now % 4][0]
nx = x + move[now % 4][1]

# 方向変換がある場合、値を1増減することで4で割って出るあまりの値を変える。
if d == 'L'
  now -= 1
else
  now += 1
end

# 枠が指定されている場合はみ出さないように判定する
h = 10
w = 10
0 <= ny && ny <= h - 1 && 0 <= nx && nx <= w - 1

累積和

配列の任意の合計を求める

array = [1, 2, 3, 4, 5, 6]
s = [0]
array.each do |i|
  s << s[-1] + i
end 
#[0, 1, 3, 6, 10, 15, 21]

いもす法
一つ前の要素との比較でどれだけ増減しているのかを記録した配列を作成し、その配列を使い累積和を作成する。
例題
店に0〜10時の間の1時間ごとに何人の客がいたかを調べる
客ごとの在席時間は2~5, 3~4, 8~10とする。

# 店の営業時間
n = 10

# 客の在席時間
people = [[2, 5], [3, 4], [7, 9]]

# 一時間前との比較
s = Array.new(n + 1, 0)
people.each do |e, l|
  s[e] += 1
  s[l + 1] -= 1
end

# s == [0, 0, 1, 1, 0, -1, -1, 1, 0, 0, -1]

times = Array.new(n + 1, 0)
times[0] = s[0]
1.upto(n) do |i|
  times[i] = times[i - 1] + s[i]
end

# times == [0, 0, 1, 2, 2, 1, 0, 1, 1, 1, 0]

二次元の累積和

縦横の累積和

s = Array.new(h + 1) { Array.new(w + 1, 0) }
0.upto(h - 1) do |y|
  0.upto(w - 1) do |x|
    # ゼータ変換
    s[y + 1][x + 1] = a[y][x] + s[y][x + 1] + s[y + 1][x] - s[y][x]
  end
end

任意の長方形の領域の総和

section.each do |a, b, c, d|
  puts s[d][c] + s[b - 1][a - 1] - s[d][a - 1] - s[b - 1][c]
end
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?