개발조아

[BOJ/백준] 백준 1022 소용돌이 예쁘게 출력하기 파이썬 본문

알고리즘/백준

[BOJ/백준] 백준 1022 소용돌이 예쁘게 출력하기 파이썬

개발조아 2021. 8. 15. 18:14
728x90

문제 링크 : https://www.acmicpc.net/problem/1022

 

1022번: 소용돌이 예쁘게 출력하기

첫째 줄에 네 정수 r1, c1, r2, c2가 주어진다.

www.acmicpc.net

 

문제에서 예시 캡처

 

위의 사진 처럼 나선형으로 숫자가 있는 배열에서 조건에 맞는 범위의 숫자를 같은길이로 예쁘게 출력하는 문제이다.

역시나 처음에는 그냥 1억개 숫자 다 만들고 했어서 역시나 메모리 초과가 났다.

 

출력해야하는 범위 칸의 개수는 최대 50x5이고 해당 범위에 들어오는 인덱스만 배열에 저장하면 된다.

 

배열의 좌표는 음수가 없으니 5000을 더해서 맞춰주고 실제 배열에 들어갈때는 이를 0,0을 기준으로 이동시켜서 넣었다. 나선형의 시작 인덱스는 당연히 5000,5000에서 시작했다.

 

예를 들어 -3 -3 0 2가 들어온다면 실제 체크해야할 범위는

(4997, 4997)에서 (5000,5002) 사이의 범위이다.

50x5 배열에 저장할 때는 r1-x로 변환하여 0,0을 기준으로 접근할수 있도록 했다.

 

나선형으로 값을 채우는 방식은 규칙을 찾아서 했다.

숫자는 오른쪽, 위, 왼쪽, 아래 순서로 저장이 진행이 된다.

 

회전은 기준 이동 횟수만큼 이동할 경우 회전이 일어나고 회전이 두번 일어나면 기준 이동 횟수도 1만큼 증가한다.

처음에 이 기준은 1이다.

숫자를 채워가다 범위에 들어오면 배열에 값을 저장하고 배열 칸의 개수만큼 채웠다면 채우는 과정을 그만한다.

 

숫자를 채우는 과정에서 숫자의 최대 길이를 저장하고

최종 결과를 출력하는 과정에서 최대 길이와 해당 숫자의 길이의 차이 만큼 공백을 출력하여 칸을 맞춰주었다.

dx = [0,-1,0,1]
dy = [1,0,-1,0]

r1,c1,r2,c2 = map(int, input().split())
r1 += 5000
c1 += 5000
r2 += 5000
c2 += 5000

board = [['0']*5 for _ in range(50)]

def set_board():
    global board
    x,y = 5000,5000
    max_length = 0
    num_cnt = 0
    d = 0
    rotate_cnt = 0
    cnt = 0
    max_cnt = 1
    num = 1
    while True:
        if r1 <= x <= r2 and c1 <= y <= c2:
            board[x-r1][y-c1] = str(num)
            max_length = max(len(str(num)), max_length)
            num_cnt += 1

            if num_cnt == (r2-r1+1)*(c2-c1+1):
                return max_length
        num += 1
        x += dx[d]
        y += dy[d]
        cnt += 1

        if cnt == max_cnt:
            d = (d+1)%4
            cnt = 0

            rotate_cnt += 1

            if rotate_cnt == 2:
                rotate_cnt = 0
                max_cnt += 1

def solv():
    max_length = set_board()
    for x in range(r2-r1+1):
        for y in range(c2-c1+1):
            print_num = ' '*(max_length-len(board[x][y]))+board[x][y]
            print(print_num,end=' ')
        print()
solv()
Comments