여니의 취준 준비/코딩테스트 (Python)

[n15722] 빙글빙글 스네일 in python

여니's 2021. 11. 4. 18:39


 

 

빙글빙글 움직일 때

위 1칸, 오른쪽 1칸, 아래 2칸, 왼쪽 2칸, 위 3칸, 오른쪽 3칸 ...

이동하는 걸 보면 규칙을 찾을 수 있다.

 

그래서 위, 오른쪽 처리는 upRight() 함수가 해주고

아래, 왼쪽 이동 처리는 downLeft() 함수가 처리해준다.

 

여기서는

dx,dy의 값을 반대로 뒤집어줘야함!

위로 올라가면 y의 값이 +1 되어야하고

아래로 내려가면 y의 값이 -1이 되어야하기 때문이다.

 

 

n=int(input())

# 위, 오른쪽, 아래, 왼쪽
dx=[0,1,0,-1]
dy=[1,0,-1,0]

x=0
y=0
num=0

def upRight():
    global x,y,n,num
    num+=1
    for _ in range(num):  # 위
        x += dx[0]
        y += dy[0]
        n -= 1
        if n == 0:
            return True
    for _ in range(num):  # 오른쪽
        x += dx[1]
        y += dy[1]
        n -= 1
        if n == 0:
            return True

def downLeft():
    global x, y, n,num
    num+=1
    for _ in range(num):  # 아래
        x += dx[2]
        y += dy[2]
        n -= 1
        if n == 0:
            return True
    for _ in range(num):  # 욀쪽
        x += dx[3]
        y += dy[3]
        n -= 1
        if n == 0:
            return True


while True:
    if upRight():
            break
    if downLeft():
        break

print(x,y)

for문을 너무 비효율적으로 많이 사용하는 것 같아서

다른 방법을 찾아보았다.

 

이 방법은 % 연산자와 // 연산자를 잘만 사용하면 빠르게 답을 

도출해낼 수 있다.

 

n=int(input())

# 위, 오른쪽, 아래, 왼쪽
dx=[0,1,0,-1]
dy=[1,0,-1,0]

x=0
y=0
cnt=0
now=0

while True:
    for _ in range(cnt//2+1): #각 방향에서 움직이는 횟수를 담당하는 for문
        if now==n: # 움직인 횟수가 n이랑 같으면 프로그램 종료
            print(x,y)
            exit()
        x+=dx[cnt%4]
        y+=dy[cnt%4]
        now+=1
    cnt+=1 # 한 방향에서 움직임이 끝났을 경우 cnt+=1


print(x,y)

일단 for문의 반복횟수는

1,1 (위,오른쪽)  : 각각 1번씩 

2,2 (아래,왼쪽) : 각각 2번씩

3,3 (위,오른쪽) 각각 3번씩

4,4 (아래,왼쪽) : 각각 4번씩

...

 

위, 오른쪽, 아래 , 왼쪽 , 방향이 총 4가지라는 것을 이용하면 쉽게 해결된다.

cnt==0 , cnt==1 일 때 //2를 처리해주면? -> 값은 0이 된다.

여기에 +1을 해주면 -> for문은 1번만 돈다 (위,오른쪽)

 

cnt==2, cnt==3일때 //2를 처리해주면? -> 값은 1이 된다.

여기에 +1을 해주면 -> for문은 2번만 돈다 (아래, 왼쪽)