結果
| 問題 |
No.1588 Connection
|
| コンテスト | |
| ユーザー |
yuruhiya
|
| 提出日時 | 2021-07-09 13:54:00 |
| 言語 | Crystal (1.14.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 5,764 bytes |
| コンパイル時間 | 14,881 ms |
| コンパイル使用メモリ | 295,824 KB |
| 実行使用メモリ | 280,292 KB |
| 平均クエリ数 | 0.28 |
| 最終ジャッジ日時 | 2024-07-17 12:56:04 |
| 合計ジャッジ時間 | 18,589 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 1 |
| other | AC * 4 TLE * 1 -- * 26 |
ソースコード
# require "/utility/Point"
struct Point
include Comparable(Point)
extend Indexable(Point)
property y : Int32, x : Int32
Direction4 = [Point.up, Point.left, Point.down, Point.right]
Direction8 = Direction4 + [Point.ul, Point.ur, Point.dl, Point.dr]
class_getter! height : Int32, width : Int32
def self.set_range(height : Int32, width : Int32)
raise ArgumentError.new unless 0 < height && 0 < width
@@height, @@width = height, width
end
def self.size
height * width
end
def self.unsafe_fetch(index : Int)
Point.new(index // Point.width, index % Point.width)
end
def initialize
@y, @x = 0, 0
end
def initialize(@y : Int32, @x : Int32)
end
def initialize(i : Int32)
raise ArgumentError.new unless 0 <= i && i < Point.size
@y, @x = i // Point.width, i % Point.width
end
def self.from(array : Array(Int32)) : self
raise ArgumentError.new unless array.size == 2
Point.new(array.unsafe_fetch(0), array.unsafe_fetch(1))
end
def self.[](y : Int32, x : Int32) : self
Point.new(y, x)
end
private macro define_direction(name, dy, dx)
def self.{{name}}
Point.new({{dy}}, {{dx}})
end
def {{name}}
Point.new(y + {{dy}}, x + {{dx}})
end
end
define_direction(zero, 0, 0)
define_direction(up, -1, 0)
define_direction(left, 0, -1)
define_direction(down, 1, 0)
define_direction(right, 0, 1)
define_direction(ul, -1, -1)
define_direction(ur, -1, 1)
define_direction(dl, 1, -1)
define_direction(dr, 1, 1)
{% for op in %w[+ - * // %] %}
def {{op.id}}(other : Point)
Point.new(y {{op.id}} other.y, x {{op.id}} other.x)
end
def {{op.id}}(other : Int32)
Point.new(y {{op.id}} other, x {{op.id}} other)
end
{% end %}
def xy
Point.new(x, y)
end
def yx
self
end
def ==(other : Point)
x == other.x && y == other.y
end
def <=>(other : Point)
to_i <=> other.to_i
end
def [](i : Int32)
return y if i == 0
return x if i == 1
raise IndexError.new
end
def succ
raise IndexError.new unless in_range? && self != Point.last
if x < Point.width - 1
Point.new(y, x + 1)
else
Point.new(y + 1, 0)
end
end
def pred
raise IndexError.new unless in_range? && self != Point.first
if x > 0
Point.new(y, x - 1)
else
Point.new(y - 1, Point.width - 1)
end
end
def in_range?
(0...Point.height).includes?(y) && (0...Point.width).includes?(x)
end
def to_i : Int32
raise IndexError.new unless in_range?
y * Point.width + x
end
def distance_square(other : Point)
(y - other.y) ** 2 + (x - other.x) ** 2
end
def distance(other : Point)
Math.sqrt(distance_square(other))
end
def manhattan(other : Point)
(y - other.y).abs + (x - other.x).abs
end
def chebyshev(other : Point)
Math.max((y - other.y).abs, (x - other.x).abs)
end
{% for i in [4, 8] %}
def adjacent{{i}}(&block) : Nil
Direction{{i}}.each do |d|
yield self + d
end
end
def adjacent{{i}}
Direction{{i}}.each.map { |p| self + p }
end
def adj{{i}}_in_range(&block) : Nil
Direction{{i}}.each do |d|
point = self + d
yield point if point.in_range?
end
end
def adj{{i}}_in_range
adjacent{{i}}.select(&.in_range?)
end
{% end %}
def to_s(io : IO) : Nil
io << '(' << y << ", " << x << ')'
end
def inspect(io : IO) : Nil
to_s(io)
end
def to_direction_char?(lrud = "LRUD") : Char?
if y == 0 && x != 0
x < 0 ? lrud[0] : lrud[1]
elsif x == 0 && y != 0
y < 0 ? lrud[2] : lrud[3]
end
end
def self.to_direction?(c : Char, lrud = "LRUD")
raise ArgumentError.new unless lrud.size == 4
lrud.index(c).try { |i| {left, right, up, down}[i] }
end
def self.to_direction?(s : String, lrud = "LRUD")
case s.size
when 1
to_direction?(s[0], lrud)
when 2
p1 = to_direction?(s[0], lrud) || return nil
p2 = to_direction?(s[1], lrud) || return nil
return nil unless p1.x ^ p2.x != 0 && p1.y ^ p2.y != 0
p1 + p2
end
end
end
module Indexable(T)
private def check_index_out_of_bounds(point : Point)
check_index_out_of_bounds(point) { raise IndexError.new }
end
private def check_index_out_of_bounds(point : Point)
if 0 <= point.y < size && 0 <= point.x < unsafe_fetch(point.y).size
point
else
yield
end
end
def fetch(point : Point)
point = check_index_out_of_bounds(point) do
return yield point
end
unsafe_fetch(point.y)[point.x]
end
def [](point : Point)
fetch(point) { raise IndexError.new }
end
def []?(point : Point)
fetch(point, nil)
end
end
class Array(T)
def []=(point : Point, value)
index = check_index_out_of_bounds point
@buffer[index.y][index.x] = value
end
end
class Manager
getter n : Int32, m : Int32
def initialize
@n, @m = read_line.split.map(&.to_i)
Point.set_range(@n, @n)
@black = Set(Point).new
@black << Point.first << Point.last
@white = Set(Point).new
end
def black?(p : Point)
if @black.size == @m
false
elsif @black.includes?(p)
true
elsif @white.includes?(p)
false
else
puts "#{p.y + 1} #{p.x + 1}"; STDOUT.flush
(read_line == "Black").tap { |flag|
if flag
@black << p
else
@white << p
end
}
end
end
end
a = Manager.new
que = Deque{Point.first}
while p = que.pop?
if p.manhattan(Point.last) == 1
puts "Yes"
exit
end
p.adj4_in_range do |p2|
if a.black?(p2)
que << p2
puts("Yes") + exit if p2.manhattan(Point.last) == 1
end
end
end
puts "No"
yuruhiya