【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))
上一篇:[LeetCode] 780. Reaching Points


下一篇:【ABAP系列】SAP ABAP下载带密码的Excel文件