はじめに
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をインクリメントします。