Submission #669900
Source Code Expand
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import array
import collections
import itertools
import sys
DELTAS = [(1, 0), (-1, 0), (0, 1), (0, -1)]
INF = 100000
INVALID = (-1, -1)
WHITE = 0
GRAY = 1
BLACK = 2
class Solver(object):
def __init__(self, stage, size, deltas=DELTAS):
self.stage = stage[:]
self.size = size
self.deltas = deltas[:]
self.hands = None
self.naive_counter = 0
self.pred = None
self.to = None
self.visited = None
self.decremented = None
self.start = (0, 0)
self.in_queue = None
self.queues = None
self.initialize_hands()
def initialize_hands(self):
self.hands = []
self.naive_counter = 0
self.decremented = collections.defaultdict(bool)
def initialize_dfs(self):
self.pred = collections.defaultdict(lambda: INVALID)
self.to = collections.defaultdict(lambda: INVALID)
self.visited = collections.defaultdict(lambda: WHITE)
self.in_queue = collections.defaultdict(bool)
self.queues = []
def decrement(self, r, c):
if self.stage[r][c] > 0:
self.hands.append((r + 1, c + 1))
self.stage[r][c] -= 1
def naive_solution(self):
for r, c in itertools.product(range(self.size), repeat=2):
cell = self.stage[r][c]
if cell > 0:
for _ in range(cell):
self.naive_counter += 1
self.decrement(r, c)
def is_valid_rc(self, r, c):
return not (r < 0 or r >= self.size or c < 0 or c >= self.size)
def start_dfs_from(self, r0, c0):
self.visited[(r0, c0)] = GRAY
if not self.is_valid_rc(r0, c0):
return
cell0 = self.stage[r0][c0]
if cell0 <= 1:
return
for dr, dc in self.deltas:
(r, c) = (r0 + dr, c0 + dc)
if not self.is_valid_rc(r, c):
continue
if self.visited[(r, c)]:
continue
cell = self.stage[r][c]
if cell0 - cell != 1:
continue
self.pred[(r, c)] = (r0, c0)
self.to[(r0, c0)] = (r, c)
self.start_dfs_from(r, c)
self.visited[(r0, c0)] = BLACK
def perform_dfs(self):
self.initialize_dfs()
for r, c in itertools.product(range(self.size), repeat=2):
if not self.visited[(r, c)]:
self.start_dfs_from(r, c)
def construct_forest(self):
self.perform_dfs()
keys = list(self.to.keys())
for r0, c0 in keys:
if self.in_queue[(r0, c0)]:
continue
q = collections.deque()
q.append((r0, c0))
r, c = r0, c0
while True:
r_next, c_next = self.to[(r, c)]
if (r_next, c_next) == INVALID:
break
q.append((r_next, c_next))
self.in_queue[(r_next, c_next)] = True
r, c = r_next, c_next
r, c = r0, c0
while True:
r_prev, c_prev = self.pred[(r, c)]
if (r_prev, c_prev) == INVALID:
break
q.appendleft((r_prev, c_prev))
self.in_queue[(r_prev, c_prev)] = True
r, c = r_prev, c_prev
self.queues.append(q)
def use_dfs_solution(self):
for _ in range(100):
self.construct_forest()
for q in self.queues:
while q:
(r0, c0) = q.popleft()
self.decrement(r0, c0)
self.naive_solution()
def search_next(self, r0, c0):
if (r0, c0) == INVALID:
return
if self.decremented[(r0, c0)]:
return
self.decrement(r0, c0)
self.decremented[(r0, c0)] = True
self.search_next(*self.to[(r0, c0)])
def main():
sys.setrecursionlimit(INF)
stage = []
for line in sys.stdin:
stage.append(array.array("B", map(int, line.split())))
size = len(stage)
solver = Solver(stage, size)
solver.use_dfs_solution()
for r, c in solver.hands:
print("{} {}".format(r, c))
if __name__ == '__main__':
main()
Submission Info
Submission Time |
|
Task |
A - 高橋君の山崩しゲーム |
User |
hamukichi |
Language |
Python (3.4.3) |
Score |
560962 |
Code Size |
4448 Byte |
Status |
AC |
Exec Time |
774 ms |
Memory |
7604 KB |
Judge Result
Set Name |
test_01 |
test_02 |
test_03 |
test_04 |
test_05 |
test_06 |
test_07 |
test_08 |
test_09 |
test_10 |
Score / Max Score |
58825 / 100000 |
54835 / 100000 |
55846 / 100000 |
53533 / 100000 |
55717 / 100000 |
55985 / 100000 |
56226 / 100000 |
58122 / 100000 |
56393 / 100000 |
55480 / 100000 |
Status |
|
|
|
|
|
|
|
|
|
|
Set Name |
Test Cases |
test_01 |
subtask_01_01.txt |
test_02 |
subtask_01_02.txt |
test_03 |
subtask_01_03.txt |
test_04 |
subtask_01_04.txt |
test_05 |
subtask_01_05.txt |
test_06 |
subtask_01_06.txt |
test_07 |
subtask_01_07.txt |
test_08 |
subtask_01_08.txt |
test_09 |
subtask_01_09.txt |
test_10 |
subtask_01_10.txt |
Case Name |
Status |
Exec Time |
Memory |
subtask_01_01.txt |
AC |
743 ms |
7488 KB |
subtask_01_02.txt |
AC |
772 ms |
7492 KB |
subtask_01_03.txt |
AC |
736 ms |
7384 KB |
subtask_01_04.txt |
AC |
753 ms |
7604 KB |
subtask_01_05.txt |
AC |
746 ms |
7368 KB |
subtask_01_06.txt |
AC |
766 ms |
7460 KB |
subtask_01_07.txt |
AC |
758 ms |
7516 KB |
subtask_01_08.txt |
AC |
745 ms |
7356 KB |
subtask_01_09.txt |
AC |
774 ms |
7548 KB |
subtask_01_10.txt |
AC |
749 ms |
7524 KB |