행렬 테두리 회전

hey hey·2022년 2월 25일
0

알고리즘

목록 보기
32/57
post-thumbnail

문제 설명
rows x columns 크기인 행렬이 있습니다. 행렬에는 1부터 rows x columns까지의 숫자가 한 줄씩 순서대로 적혀있습니다. 이 행렬에서 직사각형 모양의 범위를 여러 번 선택해, 테두리 부분에 있는 숫자들을 시계방향으로 회전시키려 합니다. 각 회전은 (x1, y1, x2, y2)인 정수 4개로 표현하며, 그 의미는 다음과 같습니다.

x1 행 y1 열부터 x2 행 y2 열까지의 영역에 해당하는 직사각형에서 테두리에 있는 숫자들을 한 칸씩 시계방향으로 회전합니다.
다음은 6 x 6 크기 행렬의 예시입니다.

grid_example.png

이 행렬에 (2, 2, 5, 4) 회전을 적용하면, 아래 그림과 같이 2행 2열부터 5행 4열까지 영역의 테두리가 시계방향으로 회전합니다. 이때, 중앙의 15와 21이 있는 영역은 회전하지 않는 것을 주의하세요.

rotation_example.png

행렬의 세로 길이(행 개수) rows, 가로 길이(열 개수) columns, 그리고 회전들의 목록 queries가 주어질 때, 각 회전들을 배열에 적용한 뒤, 그 회전에 의해 위치가 바뀐 숫자들 중 가장 작은 숫자들을 순서대로 배열에 담아 return 하도록 solution 함수를 완성해주세요.

제한사항
rows는 2 이상 100 이하인 자연수입니다.
columns는 2 이상 100 이하인 자연수입니다.
처음에 행렬에는 가로 방향으로 숫자가 1부터 하나씩 증가하면서 적혀있습니다.
즉, 아무 회전도 하지 않았을 때, i 행 j 열에 있는 숫자는 ((i-1) x columns + j)입니다.
queries의 행의 개수(회전의 개수)는 1 이상 10,000 이하입니다.
queries의 각 행은 4개의 정수 [x1, y1, x2, y2]입니다.
x1 행 y1 열부터 x2 행 y2 열까지 영역의 테두리를 시계방향으로 회전한다는 뜻입니다.
1 ≤ x1 < x2 ≤ rows, 1 ≤ y1 < y2 ≤ columns입니다.
모든 회전은 순서대로 이루어집니다.
예를 들어, 두 번째 회전에 대한 답은 첫 번째 회전을 실행한 다음, 그 상태에서 두 번째 회전을 실행했을 때 이동한 숫자 중 최솟값을 구하면 됩니다.

접근방법

  1. 테두리의 위치를 전부 저장합니다.
    • 14,8,9,10,16...20 순서로 위치를 시계방향으로 저장합니다.
  2. 테두리의 값을 전부 저장합니다
    • 똑같이 14,8,9,10,16...20 순서로 값을 저장합니다.
  3. 시계방향으로 회전 이기 때문에 맨 뒤의 20이 14자리에 가게 될 것입니다.
    • 2번의 리스트의 맨뒤의 20을 맨 앞으로 보내줍니다.
      cover.insert(0,cover.pop())
  4. 이 값들을 하나씩 1번 리스트의 위치에 다시 넣어주게 됩니다.
  5. answer의 값은 2번의 리스트의 최소값을 구해주면 됩니다.
rows, columns = 100,97
queries =[[1,1,100,97]]



def solution(rows, columns, queries):
    graph = [[0 for _ in range(columns)] for _ in range(rows)]
    num = 1
    for i in range(rows):
        for j in range(columns):
            graph[i][j] = num
            num += 1
    answer = []
    while queries:
        querie = queries.pop(0)
        cover = []
        covernum = []
        i = querie[0]-1
        j = querie[1]-1
        while [i,j] not in cover:
            if i == querie[0]-1:
                if j<querie[3]:
                    cover.append([i,j])
                    covernum.append(graph[i][j])
                    j+=1
                else: # i는 첫줄 j 가 넘어서면?
                    j-=1
                    i+=1
                    while i < querie[2]:
                        cover.append([i, j])
                        covernum.append(graph[i][j])
                        i+=1
            elif i == querie[2]:
                i-=1
                j-=1
            elif i < querie[2]:
                if j >=querie[1]-1:
                    cover.append([i, j])
                    covernum.append(graph[i][j])
                    j-=1
                else:
                    j+=1
                    i-=1
                    while i > querie[0]:
                        cover.append([i, j])
                        covernum.append(graph[i][j])
                        i-=1

        covernum.insert(0,covernum.pop())
        answer.append(min(covernum))
        for m in range(len(covernum)):
            graph[cover[m][0]][cover[m][1]] = covernum[m]

    return answer


print(solution(rows,columns,queries))
profile
FE - devp

0개의 댓글