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でAtCoder ABC275(A, B, C)を解いてみた

Last updated at Posted at 2023-04-24

はじめに

Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC275のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。

A - Find Takahashi

a-275.rb
gets
h = gets.split.map(&:to_i)
puts h.index(h.max) + 1

解説

問題文に高さは相異なるとあるので、h.maxで最大の高さを求めindexメソッドを使ってその位置を出力すればOKです。

B - ABC-DEF

b-275.rb
a, b, c, d, e, f = gets.split.map(&:to_i)
puts ((a * b * c) - (d * e * f)) % 998244353

C - Counting Squares

c-275.rb
array = Array.new(9){ gets.chomp }

ans = 0
9.times do |i|
  9.times do |j|
    next if array[i][j] == "."
    (i + 1).times do |y|
      for x in j + 1..8
        next if array[y][x] == "."
        dy = i - y
        dx = x - j
        ii = i + dx
        jj = j + dy
        yy = y + dx
        xx = x + dy
        ans += 1 if ii < 9 && jj < 9 && yy < 9 && xx < 9 && array[ii][jj] == "#" && array[yy][xx] == "#"
      end
    end
  end
end
puts ans

<追記>
ブロック付きcountを使った別解になります。

別解1
array = Array.new(9){ gets.chomp }
points = []
9.times do |i|
  9.times do |j|
    points << [i, j] if array[i][j] == "#"
  end
end

def d(x, y, nx, ny)
  (nx - x) ** 2 + (ny - y) ** 2
end

ans = points.combination(4).count do |(x0, y0), (x1, y1), (x2, y2), (x3, y3)|
  # 以下、3つの条件(位置の条件、長さの条件、対角線の長さの条件)を検証
  x3- x2 == x1 - x0 && y3 - y2 == y1 - y0 && x3- x1 == x2 - x0 && y3 - y1 == y2 - y0 &&
  d(x0, y0, x1, y1) == d(x0, y0, x2, y2) && d(x0, y0, x1, y1) == d(x2, y2, x3, y3) && d(x0, y0, x1, y1) == d(x1, y1, x3, y3) &&
  d(x0, y0, x3, y3) == d(x1, y1, x2, y2)
end
puts ans
別解2
array = Array.new(9){ gets.chomp }
points = []
9.times do |r|
  9.times do |c|
    points << [r, c] if array[r][c] == "#"
  end
end

ans = points.combination(4).count do |(r0, c0), (r1, c1), (r2, c2), (r3, c3)|
  dr = r1 - r0
  dc = c1 - c0
  next if r3 - r2 != dr || r2 - r1 != dc.abs - dr || c3 - c2 != dc
  
  if dc >= 0
    c1 - c2 == dc + dr.abs
  else
    c2 - c1 == dc.abs + dr.abs
  end
end
puts ans

<追記>
コメントでいただいた別解になります。

別解3
require "matrix"

def get_4_apexes(x, y)
  (1..8).each do |len|
    (1..len).each do |vx|
      v = Vector[vx, len - vx]
      pt = Vector[x, y]
      apexes = 4.times.map {
        pt += v
        v = Matrix[[0, -1], [1, 0]] * v
        pt
      }
      f = apexes.all? {|pt|
        0 <= pt[0] && pt[0] <= 8 && 0 <= pt[1] && pt[1] <= 8
      }
      yield(apexes) if f
    end
  end
end

field = Array.new(9) { gets.chomp }

puts 8.times.sum {|x|
  8.times.sum {|y|
    enum_for(:get_4_apexes, x, y).count {|apexes|
      apexes.all? { |pt| field[pt[1]][pt[0]] == "#" }
    }
  }
}

解説

(他の方の提出結果を参考にしました)

yは前の行、xは後ろの列を表し、array[i][j]=="#"かつarray[y][x]=="#"であるような位置で正方形の4点の内2点を固定します。そして、正方形であることを利用してiとyの差分dyおよびjとxの差分dxから残った2つの点(ii,jj)と(yy,xx)を求めます。最後に、これらの点が縦横の大きさがともに9の二次元平面内にあればansをインクリメントします。

0
0
5

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?