CSES - Datatähti 2022 loppu - Results
Submission details
Task:Sokkelo
Sender:okkokko
Submission time:2023-01-21 21:02:41 +0200
Language:Python3 (PyPy3)
Status:READY
Result:0
Feedback
groupverdictscore
#10
#20
Test results
testverdicttimegroup
#10.05 s1, 2details
#2ACCEPTED0.05 s1, 2details
#3ACCEPTED0.05 s1, 2details
#40.07 s2details
#5ACCEPTED0.47 s2details
#6ACCEPTED0.41 s2details
#7ACCEPTED0.04 s1, 2details
#8ACCEPTED0.20 s2details
#9--2details
#10ACCEPTED0.06 s1, 2details
#11--2details
#12ACCEPTED0.04 s1, 2details
#13ACCEPTED0.17 s2details
#14ACCEPTED0.04 s1, 2details
#15ACCEPTED0.11 s2details
#160.04 s2details
#170.06 s2details

Code

# 2022 loppu C
n, m = map(int, input().split())
rivit = [input() for _ in range(n)]
# let's try generating outlines of walls
# 3
# 2 0
# 1
def find_letter(letter: str):
for i in range(n):
a = rivit[i].find(letter)
if a != -1:
return a, i
raise TypeError()
A_pos = find_letter("A")
B_pos = find_letter("B")
def is_path(x: int, y: int):
return rivit[y][x] != "#"
def advance(x: int, y: int, d: int):
d %= 4
if d == 0:
return x + 1, y
elif d == 1:
return x, y + 1
elif d == 2:
return x - 1, y
elif d == 3:
return x, y - 1
raise TypeError()
class IsSurrounded(Exception):
...
class IsConnected(Exception):
...
def step_outline(x: int, y: int, d: int):
for i in range(4):
a, b = advance(x, y, d + i - 1)
if is_path(a, b):
return a, b, d + i - 1
raise IsSurrounded()
def cast_ray(x: int, y: int, d: int):
while 1:
a, b = advance(x, y, d)
if is_path(a, b):
x, y = a, b
else:
return x, y
def seek_advance(x: int, y: int, tx: int, ty: int):
"returns new position, direction"
if abs(x - tx) > abs(y - ty):
if x > tx:
return x - 1, y, 2
else:
return x + 1, y, 0
else:
if y > ty:
return x, y - 1, 3
else:
return x, y + 1, 1
def seek_ray(x: int, y: int, tx: int, ty: int):
while 1:
a, b, d = seek_advance(x, y, tx, ty)
if a == tx and b == ty:
raise IsConnected()
if is_path(a, b):
x, y = a, b
else:
return x, y, d
def generate_outline(x: int, y: int, d: int):
"""returns the points of the outline, whether it is an interior outline, and a point at the opposite end (granted d is 1).
\n tracing an outline must start at a point where there is a wall at the d-1 direction"""
a, b, d = step_outline(x, y, d)
start_d = d
points: "list[tuple[int,int]]" = [(a, b)]
opposite_x = x # largest x coordinate with y as the y parameter. currently works only if d parameter is 1
while 1:
a, b, d = step_outline(*points[-1], d)
if (a, b) == points[0] and d % 4 == start_d % 4:
assert(abs(d - start_d) == 4)
# d - start_d == 4 means this is inside, == -4 means this is outside
is_interior = (d - start_d == 4)
return points, is_interior, (opposite_x, y)
points.append((a, b))
if b == y and opposite_x < a:
opposite_x = a
def get_bound(x: int, y: int):
"get the interior outline (x,y) is inside of"
try:
step_outline(x, y, 0)
except IsSurrounded:
return [(x, y)]
a, b = x, y
while 1:
a, b = cast_ray(a, b, 0)
points, is_interior, opposite = generate_outline(a, b, 1)
if is_interior:
return points
a, b = opposite
def is_inside(x: int, y: int, outline: "list[tuple[int,int]]"):
"is the point x,y inside the area marked by the outline?"
if (x, y) in outline:
return True
l = len(outline)
if l == 1:
return False
downs = 0
for i in range(l):
if outline[i][1] == y and outline[i][0] < x:
downs += outline[i - 1][1] - outline[(i + 1) % l][1]
return downs != 0
import itertools
def manhattan(a: "tuple[int,int]", b: "tuple[int,int]"):
return abs(a[0] - b[0]) + abs(a[1] - b[1])
def manhattan2(ax: int, ay: int, bx: int, by: int):
return abs(ax - bx) + abs(ay - by)
def outline_distance(a: "list[tuple[int,int]]", b: "list[tuple[int,int]]"):
return min(manhattan(c, d) for c, d in itertools.product(a, b))
def closest_in_outline(x: int, y: int, outline: "list[tuple[int,int]]"):
def key(k):
return manhattan2(x, y, *k)
return min(outline, key=key)
def get_bound_seek(x: int, y: int, tx: int, ty: int):
"get the outline closest to (tx,ty) that can be reached from (x,y)"
try:
step_outline(x, y, 0)
except IsSurrounded:
return [(x, y)]
a, b = x, y
while 1:
a, b, d = seek_ray(a, b, tx, ty)
outline, is_interior, opposite = generate_outline(a, b, d + 1)
is_in = is_inside(tx, ty, outline)
# print(a, b, d, tx, ty, is_interior, is_in, outline)
if is_interior and not is_in:
return outline
elif is_in and not is_interior:
return outline
a, b = closest_in_outline(tx, ty, outline)
try:
A_bound = get_bound_seek(*A_pos, *B_pos)
B_bound = get_bound_seek(*B_pos, *A_pos)
except IsConnected:
print(0)
else:
print(outline_distance(A_bound, B_bound))

Test details

Test 1

Group: 1, 2

Verdict:

input
20 20
####################
#A.................#
#..................#
#..................#
...

correct output
1

user output
0

Test 2

Group: 1, 2

Verdict: ACCEPTED

input
20 20
####################
#A.................#
#..................#
#..................#
...

correct output
2

user output
2

Test 3

Group: 1, 2

Verdict: ACCEPTED

input
20 20
####################
#A.................#
#..................#
#..................#
...

correct output
9

user output
9

Test 4

Group: 2

Verdict:

input
1000 1000
##############################...

correct output
1

user output
0

Test 5

Group: 2

Verdict: ACCEPTED

input
1000 1000
##############################...

correct output
2

user output
2

Test 6

Group: 2

Verdict: ACCEPTED

input
1000 1000
##############################...

correct output
335

user output
335

Test 7

Group: 1, 2

Verdict: ACCEPTED

input
20 20
####################
#####.##############
###.....############
##.......###########
...

correct output
10

user output
10

Test 8

Group: 2

Verdict: ACCEPTED

input
1000 1000
##############################...

correct output
436

user output
436

Test 9

Group: 2

Verdict:

input
1000 1000
##############################...

correct output
2

user output
(empty)

Test 10

Group: 1, 2

Verdict: ACCEPTED

input
20 20
####################
#B................##
#################.##
#################.##
...

correct output
2

user output
2

Test 11

Group: 2

Verdict:

input
1000 1000
##############################...

correct output
2

user output
(empty)

Test 12

Group: 1, 2

Verdict: ACCEPTED

input
20 20
####################
##########A#########
##########.#########
##########.#########
...

correct output
2

user output
2

Test 13

Group: 2

Verdict: ACCEPTED

input
1000 1000
##############################...

correct output
2

user output
2

Test 14

Group: 1, 2

Verdict: ACCEPTED

input
20 20
####################
##########A#########
##########.#########
##########.#########
...

correct output
12

user output
12

Test 15

Group: 2

Verdict: ACCEPTED

input
1000 1000
##############################...

correct output
502

user output
502

Test 16

Group: 2

Verdict:

input
3 1000
##############################...

correct output
1

user output
0

Test 17

Group: 2

Verdict:

input
1000 3
###
#A#
#.#
#.#
...

correct output
1

user output
0