Submission #148465


Source Code Expand

#!/usr/bin/env python2.7

import sys
from collections import defaultdict

from cStringIO import StringIO
import unittest
import cProfile

def main():
    R, C, K = (int(x) for x in sys.stdin.readline().split())
    F = []
    for _ in range(R):
        f, = [x for x in sys.stdin.readline().split()]
        F.append(f)
    print solve(R, C, K, F)

def findPos(F, c):
    for y, l in enumerate(F):
        for x, t in enumerate(l):
            if t == c:
                return x, y

def nextpos(x, y):
    yield x+1, y
    yield x, y+1
    yield x-1, y
    yield x, y-1

NOWAY = 1000000

def calcdp(F, K, s):
    R = len(F)
    C = len(F[0])
    Es = []
    for y in range(R):
        for x in range(C):
            if F[y][x] == 'E':
                Es.append((x,y))

    dp = []

    nn = [(0, s)]
    dd = [[NOWAY for _ in range(C)] for _ in range(R)]

    for k in range(K+1):
        while len(nn) > 0:
            (t, (px, py)) = nn.pop(0)
            if dd[py][px] <= t:
                continue
            dd[py][px] = t
            for nx, ny in nextpos(px, py):
                c = F[ny][nx]
                if c != 'T' and c != 'E':
                    nn.append((t+1, (nx, ny)))
        dp.append(dd)
        dd = [[dd[y][x] for x in range(C)] for y in range(R)]
        for ex, ey in Es:
            t = min([dd[y][x] for x, y in nextpos(ex, ey)]) + 1
            if t < dd[ey][ex]:
                nn.append((t, (ex, ey)))
        nn.sort()

    return dp


def solve(R, C, K, F):
    R += 2
    C += 2
    F = ["T" * C] + [["T"] + list(l) + ["T"] for l in F] + ["T" * C]

    s = findPos(F, "S")
    c = findPos(F, "C")
    g = findPos(F, "G")

    dps = calcdp(F, K, s)
    dpc = calcdp(F, K, c)
    dpg = calcdp(F, K, g)
    
    m = NOWAY
    for y in xrange(R):
        for x in xrange(C):
            t = F[y][x] == 'E'
            for k1 in xrange(K + 1):
                if k1 != 0 and dps[k1-1][y][x] == dps[k1][y][x]:
                    continue
                for k2 in xrange(K + 1):
                    k3 = K - k1 - k2 + t * 2
                    if k3 < 0 or K < k3:
                        continue
                    d = dps[k1][y][x] + dpc[k2][y][x] * 2 + dpg[k3][y][x]
                    if d < m:
                        m = d
    if m == NOWAY:
        return -1
    return m
    
class Test(unittest.TestCase):

    @staticmethod
    def tryone(indata):
        sys.stdin = StringIO(indata)
        out = sys.stdout = StringIO()
        main()
        return out.getvalue()

    def test20(self):
        self.assertEqual(calcdp([
            "TTTTTTT",
            "T.T.E.T",
            "T.E.T.T",
            "TTTTTTT",
            ], 2, (1,1)),
            [[
                [NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, ],
                [NOWAY,     0, NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, ],
                [NOWAY,     1, NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, ],
                [NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, ],
            ],[
                [NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, ],
                [NOWAY,     0, NOWAY,     4, NOWAY, NOWAY, NOWAY, ],
                [NOWAY,     1,     2,     3, NOWAY, NOWAY, NOWAY, ],
                [NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, ],
            ],[
                [NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, ],
                [NOWAY,     0, NOWAY,     4,     5,     6, NOWAY, ],
                [NOWAY,     1,     2,     3, NOWAY,     7, NOWAY, ],
                [NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, NOWAY, ],
            ]])

    def test30(self):
        self.assertEqual(findPos([
            "GET..ET",
            "..T....",
            ".TEST..",
            ".E.T.ET",
            "...ETC.",
        ], "S"), (3,2))

    def test50(self):
        self.assertEqual(solve(5, 7, 3, [
            "GET..ET",
            "..T....",
            ".TEST..",
            ".E.T.ET",
            "...ETC.",
        ]), 19)

    def test80(self):
        solve(50, 50, 100, 
            ["S................................................."] +
            [".................................................."] * 48 +
            ["C................................................G"]
        )

    def test81(self):
        F = ["S................................................."];
        for _ in range(24):
            F.append("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.")
            F.append("..................................................")
        F.append("C................................................G")
        solve(50, 50, 100, F)

    def test91(self):
        self.assertEqual(self.tryone("""\
5 7 3
GET..ET
..T....
.TEST..
.E.T.ET
...ETC.
"""), """19\n""")

    def test92(self):
        self.assertEqual(self.tryone("""\
5 7 2
GET..ET
..T....
.TEST..
.E.T.ET
...ETC.
"""), """21\n""")

    def test93(self):
        self.assertEqual(self.tryone("""\
5 7 1
GET..ET
..T....
.TEST..
.E.T.ET
...ETC.
"""), """-1\n""")

    def test94(self):
        self.assertEqual(self.tryone("""\
6 35 4
T...TT.....TT...TTT...TTT..TTG.....
..T..T.TTT.T..T..E..T..E...TTT.TTT.
.TTT.T.....E.TTTTT.TTT.TTT.TTT.....
.....T.TT.TT.TTTTT.TTT.TTT.TTTTTTT.
.TTT.T.TT..T..T..S..T..TTT.TTTTTTT.
.CTT.E.TTT.TT...TTT...TT.....E.....
"""), """94\n""")

if __name__ == '__main__':
    if len(sys.argv) > 1:
        print "_/" * 30 + str(sys.argv)
        if sys.argv[1] == '-p':
            sys.argv.pop(1)
            cProfile.run("unittest.main(exit=False, failfast=True)", sort='time')
        else:
            unittest.main()
    else:
        main()

Submission Info

Submission Time
Task C - 最後の森
User over80
Language Python (2.7.3)
Score 100
Code Size 5824 Byte
Status AC
Exec Time 1798 ms
Memory 13400 KB

Judge Result

Set Name All
Score / Max Score 100 / 100
Status
AC × 30
Set Name Test Cases
All case_01.txt, case_02.txt, case_03.txt, case_04.txt, case_05.txt, case_06.txt, case_07.txt, case_08.txt, case_09.txt, case_10.txt, case_11.txt, case_12.txt, case_13.txt, case_14.txt, case_15.txt, case_16.txt, case_17.txt, case_18.txt, case_19.txt, case_20.txt, case_21.txt, case_22.txt, case_23.txt, case_24.txt, case_25.txt, case_26.txt, case_27.txt, case_28.txt, case_29.txt, case_30.txt
Case Name Status Exec Time Memory
case_01.txt AC 185 ms 4432 KB
case_02.txt AC 72 ms 4388 KB
case_03.txt AC 73 ms 4432 KB
case_04.txt AC 70 ms 4336 KB
case_05.txt AC 71 ms 4436 KB
case_06.txt AC 75 ms 4440 KB
case_07.txt AC 79 ms 4388 KB
case_08.txt AC 124 ms 5324 KB
case_09.txt AC 87 ms 4696 KB
case_10.txt AC 88 ms 4644 KB
case_11.txt AC 89 ms 4768 KB
case_12.txt AC 81 ms 4444 KB
case_13.txt AC 165 ms 5328 KB
case_14.txt AC 965 ms 13276 KB
case_15.txt AC 729 ms 13272 KB
case_16.txt AC 244 ms 6308 KB
case_17.txt AC 1798 ms 13400 KB
case_18.txt AC 98 ms 4812 KB
case_19.txt AC 1125 ms 9180 KB
case_20.txt AC 463 ms 13064 KB
case_21.txt AC 1212 ms 13264 KB
case_22.txt AC 155 ms 5336 KB
case_23.txt AC 968 ms 13256 KB
case_24.txt AC 301 ms 6308 KB
case_25.txt AC 765 ms 11604 KB
case_26.txt AC 240 ms 6988 KB
case_27.txt AC 1077 ms 13216 KB
case_28.txt AC 496 ms 12500 KB
case_29.txt AC 101 ms 4568 KB
case_30.txt AC 170 ms 4944 KB
sample_01.txt AC 73 ms 4444 KB
sample_02.txt AC 73 ms 4440 KB
sample_03.txt AC 71 ms 4436 KB
sample_04.txt AC 74 ms 4560 KB