【Kickstart】2019 Round C - Wiggle Walk

解法

rc個點映射到一維ID,然後維護4個方向的並查集:
比如E方向的並查集,最開始,每個點都代表它自己,當某個點被訪問過之後,如果有人向東走到了這個點,那麼它應該直接走到這個點東邊第一個沒有被訪問的點,那就是這個點的root

所以算法應該是這樣的,對於每個被訪問到的點x,找到它周圍四個點e``w``s``n,然後E.join(x,e),……
join的時候要注意順序,使得根永遠是一個沒被訪問過的節點
然後移動就用find來移動

# -*- coding:utf-8 -*-

class UN(object):
    def __init__(self):
        self.f = {}

    def find(self,x):
        if x not in self.f:
            self.f[x] = x
        r = x
        while self.f[r]!=r:
            r = self.f[r]
        while self.f[x]!=r:
            tmp = self.f[x]
            self.f[x] = r
            x = tmp
        return r

    def join(self,x,y):
        rx,ry = self.find(x), self.find(y)
        self.f[rx] = ry


def solve(r,c,sx,sy,OPT):
    E,W,N,S = UN(),UN(),UN(),UN()
    def getId(x,y):
        return c*x + y
    now = getId(sx,sy)
    e,w,n,s = getId(sx,sy+1), getId(sx,sy-1), getId(sx-1,sy), getId(sx+1,sy)
    E.join(now, e)
    W.join(now,w)
    N.join(now,n)
    S.join(now,s)
    for opt in OPT:
        if opt == 'E':
            now = E.find(now)
        elif opt == 'S':
            now = S.find(now)
        elif opt == 'W':
            now = W.find(now)
        elif opt == 'N':
            now = N.find(now)
        sx,sy  = now//c, now%c
        e,w,n,s = getId(sx,sy+1), getId(sx,sy-1), getId(sx-1,sy), getId(sx+1,sy)
        E.join(now, e)
        W.join(now,w)
        N.join(now,n)
        S.join(now,s)
    return now//c, now%c

if __name__ == "__main__" :
    t = int(input())
    for round in range(1,t+1):
        n,r,c,sx,sy = map(int,input().split())
        OPT = input()
        x, y = solve(r,c,sx-1,sy-1, OPT)
        print("Case #%d: %d %d"%(round,x+1,y+1))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章