Skip to content

Instantly share code, notes, and snippets.

@s890081tonyhsu
Created February 4, 2020 18:23
Show Gist options
  • Save s890081tonyhsu/ceb68c4ffe08397b07006af09021d566 to your computer and use it in GitHub Desktop.
Save s890081tonyhsu/ceb68c4ffe08397b07006af09021d566 to your computer and use it in GitHub Desktop.
有名なプールサイド [MISSION LEVEL: A] @ エンジニアが死滅シタ世界〜アンドロイドとふたりぼっちで生きろ〜 paiza.jp (Ruby solution from python solution: https://paiza.hatenablog.com/entry/2019/03/28/Python%E3%81%A7%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%95%8F%E9%A1%8C%E8%A7%A3%E3%81%8D%E3%81%A4%E3%81%A4%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%82%92
$dx = [1, 0, -1, 0]
$dy = [0, -1, 0, 1]
class TownMap
def initialize(h, w)
@h = h
@w = w
@Mat = Array.new(@h) { Array.new(@w, 0) }
@Ent = Array.new(@h) { Array.new(@w, 0)}
end
def put(building, x, y)
(0..building.h-1).each do |i|
(0..building.w-1).each do |j|
@Mat[y+i][x+j] = building.no
end
end
@Ent[y+building.r][x+building.c] = building.no
end
def inRange(x, y)
return ((0 <= x and x < @w) and (0 <= y and y < @h))
end
def isIntersect(building, x, y)
(0..building.h-1).each do |i|
(0..building.w-1).each do |j|
return 1 if @Mat[y+i][x+j] != 0
end
end
return nil
end
def isEntrancesOnOuterEdge(building, x, y)
(0..3).each do |d|
edge = building.outerEdge(d)
edge.each do |e|
ex = x + e[0]
ey = y + e[1]
return 1 if inRange(ex, ey) and @Ent[ey][ex] != 0
end
end
return nil
end
def isEntranceBlocked(building, x, y)
emptyCount = 0
(0..3).each do |d|
ax = x + building.c + $dx[d]
ay = y + building.r + $dy[d]
emptyCount += 1 if inRange(ax, ay) and !building.contains(x, y, ax, ay) and @Mat[ay][ax] == 0
end
return emptyCount == 0
end
def countContinuousObjectOnOuterEdge(building, x, y)
count = 0
start = nil
(0..3).each do |d|
edge = building.outerEdge(d)
edge.each do |e|
ex = x + e[0]
ey = y + e[1]
if !inRange(ex, ey) or @Mat[ey][ex] != 0
if not start
start = 1
count += 1
end
count -= 1 if d == 3 and e == edge[-1]
else
start = nil
end
end
end
return count
end
def canPut(building, x, y)
return nil if !inRange(x, y) or !inRange(x + building.w - 1, y + building.h - 1)
return nil if isIntersect(building, x, y)
return nil if isEntrancesOnOuterEdge(building, x, y)
return nil if isEntranceBlocked(building, x, y)
return nil if countContinuousObjectOnOuterEdge(building, x, y) >= 2
return 1
end
def result(debug = nil)
@Mat.each_index do |i|
@Mat[i].each_index do |j|
if debug
print "%4d%s" % [@Mat[i][j], if @Ent[i][j] != 0 then "*" else " " end]
else
print "%s%d" % [if j != 0 then " " else "" end, @Mat[i][j]]
end
end
puts ""
end
end
end
class Building
def initialize(no, h, w, r, c)
@no = no
@h = h
@w = w
@r = r
@c = c
end
def contains(bx, by, x, y)
return ((bx <= x and x < bx+@w) and (by <= y and y < by+@h))
end
def outerEdge(d)
edge = Array.new
if d == 0
(0..@h+1).each {|i| edge << [@w, @h-i] }
elsif d == 1
(0..@w+1).each {|i| edge << [i-1, -1] }
elsif d == 2
(0..@h+1).each {|i| edge << [-1, i-1] }
else
(0..@w+1).each {|i| edge << [@w-i, @h] }
end
return edge
end
def no
@no
end
def h
@h
end
def w
@w
end
def r
@r
end
def c
@c
end
end
H, W, N = gets.chomp.split(" ").map(&:to_i)
townMap = TownMap.new(H, W)
buildingList = Array.new
(0..N-1).each do |i|
bh, bw, br, bc = gets.chomp.split(" ").map(&:to_i)
buildingList.push(Building.new(i+1, bh, bw, br-1, bc-1))
end
count = 0
x = y = 0
buildingList.each do |building|
putOK = nil
(0..H-1).each do |y|
(0..W-1).each do |x|
next if putOK
if townMap.canPut(building, x, y)
townMap.put(building, x, y)
count += 1
putOK = 1
end
end
end
end
townMap.result()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment