상세 컨텐츠

본문 제목

[코드트리] 술래잡기(파이썬) 2022 삼성 코딩테스트 상반기 기출

알고리즘 공부

by Tabris4547 2022. 10. 6. 18:45

본문

728x90

https://www.codetree.ai/frequent-problems/hide-and-seek/explanation

 

코드트리

국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.

www.codetree.ai

코테 시험볼 때 '봤었던'문제.

삼성 코테 특성상

하나라도 제대로 푸는 게 좋다고 들어서

이 문제는 읽고

'겁나 오래 걸리겠다'

하고 넘겼습니다.

(물론 다른 문제도 제대로 못품...아앗...)

 

이 문제에서 어려웠던 부분은

술래가 어떻게 움직이는지 구현하는 것.

아마 처음 저걸 보면

진짜 뭐지???

하는 생각이 듭니다.

그냥 중앙에서 움직이는 것까지는 그렇다치는데

밖에서 다시 돌아온다고??

이게 뭐야???

라는 생각이 왕왕 듭니다.

 

저는 이렇게 설계했습니다.

1. 각각 얼마나 이동할 수 있지?

2. 중앙->밖/ 밖->중앙 이동할 때 각각 어떻게 되지??

예를들면 1 1 2 2 3 3 3 이렇게 밖으로 움직이면

3 3 3 2 2 1 1 이렇게 안으로 움직입니다.

저는 초반에 이렇게 움직이는 경로를 다 구한다음에

turn이라는 변수를 두어

중앙출발-->False

밖출발-->True

이렇게 해서 들낙하는 거 구현해줬습니다.

(k값을 일부로 100이상 돌려가면서

구현이 제대로 되었나 확인도 했습니다.)

 

저는 이 문제를 풀 때 뻘짓을 많이 했습니다.

문제를 제대로 안 읽었는데요...

뻘짓했던 걸 적어보면

1. 술레가 움직이고 도망자가 움직이는 줄 암.

2. 그러니 도망자가 시야에 안걸리면 된다고 생각함.

3. 술레가 있는 자리는 무조건 보는 줄 알았음.

 

그런데

1-->도망자가 먼저 이동

2-->도망자가 먼저 이동하고 술레가 이동하니

2는 아무 의미없음

3. 예제 3을 보면 술레가 있는 자리에 나무가 있으면 못봄.

 

이런 뻘짓때문에 

좀 많이 헤맸네요, ㅎ...

n,m,h,k=map(int,input().split())

dx=[-1,0,1,0]
dy=[0,1,0,-1]
room=[[[]for _ in range(n)] for _ in range(n)]

runner=[]
for o in range(m):
    x,y,fd=map(int,input().split())
    if fd==1:
        runner.append((x-1,y-1,1))
    elif fd==2:
        runner.append((x-1,y-1,2))

tree=set()
for _ in range(h):
    x,y=map(int,input().split())
    tree.add((x-1,y-1))
sx,sy,sd=n//2,n//2,0
turn=False
go=[]
go_re=[]
for i in range(1,n):
    go.append(i)
    go.append(i)
go.append(n-1)
go_re.append(n-1)
for i in range(n-1,0,-1):
    go_re.append(i)
    go_re.append(i)


turn=False
t_max=1
m_p=0
m_max=go[m_p]
move=0


answer=0
for t in range(1,k+1):
    #1.도망자 이동

    for k in range(len(runner)):
        rx,ry,rd=runner[k]
        dis=abs(sx-rx)+abs(sy-ry)
        if dis<=3:

            nx=rx+dx[rd]
            ny=ry+dy[rd]
            if 0<=nx<n and 0<=ny<n:

                if not [nx,ny]==[sx,sy]:
                    runner[k]=(nx,ny,rd)

            else:
                nrd=(rd+2)%4
                nx = rx + dx[nrd]
                ny = ry + dy[nrd]
                if 0 <= nx < n and 0 <= ny < n:

                    if not [nx,ny]==[sx,sy]:

                        runner[k] =(nx, ny, nrd)


    #2. 술래이동
    sx+=dx[sd]
    sy+=dy[sd]
    move+=1
    #중앙에서 밖으로
    if turn==False:
        if move==m_max:
            move=0
            m_p+=1
            if m_p==len(go):
                turn=True
                sd=(sd+2)%4
                m_p=0
                m_max=go_re[m_p]
                #print('turn')
            else:
                m_max=go[m_p]
                sd=(sd+1)%4
    #밖에서 중앙으로
    else:
        if move==m_max:
            move=0
            m_p+=1
            if m_p==len(go_re):
                turn=False
                sd=(sd-2)%4
                m_p=0
                #print('back')
            else:
                m_max=go_re[m_p]
                sd=(sd-1)%4
    #print(sx,sy)
    #시야장소 보기

    popping=[]
    see=[]
    for g in range(3):
        nx=sx+dx[sd]*g
        ny=sy+dy[sd]*g
        if (nx,ny) in tree:
            continue
        see.append((nx,ny))

    for px,py,pd in runner:
        if (px,py) in see:
            popping.append((px,py,pd))
    # print(see)
    # print(runner)
    # print(t,popping)
    # print()
    score=t*len(popping)
    answer+=score
    for px,py,pd in popping:
        ind=runner.index((px,py,pd))
        runner.pop(ind)





    # print(runner)
    # print(popping)
    # score+=t*(len(popping))
    # for px,py,pd in popping:
    #     ind=runner.index((px,py,pd))
    #     runner.pop(ind)
    # answer+=score

print(answer)

 

주석처리한 부분은

실제로 출력하면서

이게 왜 틀리지??

했던 부분들입니다.

삼성유형은 '풀만한데?'라는 생각이 들더라도

디버깅이 빡센 게 많습니다.

이 문제도 설계하는 것까지는 괜찮았는데

막상 돌렸을 때 디버깅하는 부분에서

애를 많이 먹었습니다.

문제설계할 때 처음부터 꼼꼼히 적어보는 습관이 중요해보이네요.

728x90

관련글 더보기

댓글 영역