본문 바로가기
백준알고리즘/구현

(Python/플4)백준알고리즘 117470번: 배열 돌리기 5

by windy7271 2024. 10. 13.
728x90
반응형

문제 바로가기 

 

문제:

크기가 N×M인 배열이 있을 때, 배열에 연산을 R번 적용하려고 한다. 연산은 총 6가지가 있다. 1번 연산은 배열을 상하 반전시키는 연산이다.

입력:

첫째 줄에 배열의 크기 N, M과 수행해야 하는 연산의 수 R이 주어진다. 둘째 줄부터 N개의 줄에 배열 A의 원소 Aij가 주어진다. 마지막 줄에는 수행해야 하는 연산이 주어진다. 연산은 공백으로 구분되어져 있고, 문제에서 설명한 연산 번호이며, 순서대로 적용시켜야 한다.

 

출력:

입력으로 주어진 배열에 R개의 연산을 순서대로 수행한 결과를 출력한다.

 

제한 :

2 ≤ N, M ≤ 100

1 ≤ R ≤ 2,000,000

N, M은 짝수

1 ≤ Aij ≤ 108

 

풀이:

 

R이 2,000,000 이기 때문에 그냥 매번 수행하면 배열을 건드리기 때문에 시간초과가난다.

 

마지막에 어떤것을 해야할지 저장해두고 마지막에만 수행해줘야한다.

 

 

일단 틀린풀이를 보여주겠다.

import sys


n, m, r = map(int, sys.stdin.readline().rstrip().split())

graph = [list(map(int, sys.stdin.readline().rstrip().split())) for _ in range(n)]
orders = list(map(int, sys.stdin.readline().rstrip().split()))


def number_1(pattern):
    return pattern[::-1]


def number_2(pattern):
    return [row[::-1] for row in graph]


# 왼쪽
def number_3(pattern):
    return list(list(zip(*pattern[::-1])))

# 왼쪽
def number_4(pattern):
    return list(zip(*pattern))[::-1]


def number_5(graph):
    N = len(graph)  # 행의 수
    M = len(graph[0])  # 열의 수

    new_graph = []

    # 왼쪽 아래쪽 절반 가져오고 위쪽 절반 이어붙이기
    for left in range(N // 2):
        new_row = graph[N // 2 + left][:M // 2] + graph[left][:M // 2]
        new_graph.append(new_row)
    # 오른쪽 아래 절반 가져오고 위쪽 절반 이어 붙이기
    for right in range(N // 2):
        new_row = graph[N // 2 + right][M // 2::] + graph[right][M // 2::]
        new_graph.append(new_row)

    return new_graph


def number_6(graph):
    N = len(graph)  # 행
    M = len(graph[0])  # 열

    new_graph = []

    # 위에 N//2 줄
    for right in range(N // 2):
        new_row = graph[right][M // 2::] + graph[N // 2 + right][M // 2::]
        new_graph.append(new_row)
    for left in range(N // 2):
        new_row = graph[left][:M // 2] + graph[N // 2 + left][:M // 2]
        new_graph.append(new_row)
    return new_graph

for order in orders:
    if order == 1:
        graph = number_1(graph)
    elif order == 2:
        graph = number_2(graph)
    elif order == 3:
        graph = number_3(graph)
    elif order == 4:
        graph = number_4(graph)
    else:
        if order == 5:
            graph = number_5(graph)
        if order == 6:
            graph = number_6(graph)
for i in graph:
    print(*i)

 

 

정답풀이:

import sys

sys.stdin = open('/Users/song/Desktop/Python/Python/h.txt', 'r')

n, m, r = map(int, sys.stdin.readline().rstrip().split())

graph = [list(map(int, sys.stdin.readline().rstrip().split())) for _ in range(n)]
orders = list(map(int, sys.stdin.readline().rstrip().split()))
List = [[0, 1], [3, 2]]
# 상하반전여부, 좌우반전여부, 회전방향여부
result = [False, False, 0]

def number_1():
    # 좌우 먼저 하고 돌리면 됨
    if result[2] % 2:
        result[1] = not result[1]
    else:
        result[0] = not result[0]

    global List
    # 뒤집어
    List[0], List[1] = List[1], List[0]


def number_2():
    # 위에랑 반대로 가면됨
    if result[2] % 2:
        result[0] = not result[0]
    else:
        result[1] = not result[1]

    global List

    List[0][1], List[0][0] = List[0][0], List[0][1]
    List[1][1], List[1][0] = List[1][0], List[1][1]


# 왼쪽
def number_3():
    # 회전 체크
    result[2] = (result[2] + 1) % 4
    # 돌려
    number_5()


# 왼쪽
def number_4():
    # 회전 체크
    result[2] = (result[2] - 1) % 4
    # 돌려
    number_6()


def number_5():
    global List


    new_sample = [[0, 0], [0, 0]]

    new_sample[0][0] = List[1][0]
    new_sample[0][1] = List[0][0]
    new_sample[1][0] = List[1][1]
    new_sample[1][1] = List[0][1]

    List = new_sample.copy()


def number_6():
    global List
    new_sample = [[0, 0], [0,  0]]

    new_sample[0][0] = List[0][1]
    new_sample[0][1] = List[1][1]
    new_sample[1][0] = List[0][0]
    new_sample[1][1] = List[1][0]

    List = new_sample.copy()


# 우회전
def rotate(pattern):
    return list(list(zip(*pattern[::-1])))


for order in orders:
    if order == 1:
        number_1()
    elif order == 2:
        number_2()
    elif order == 3:
        number_3()
    elif order == 4:
        number_4()
    elif order == 5:
        number_5()
    elif order == 6:
        number_6()
N = n // 2
M = m // 2
section = [[row[:M] for row in graph[:N]], [row[M:] for row in graph[:N]], [row[M:] for row in graph[N:]],
           [row[:M] for row in graph[N:]]]
# 상하반전
if result[0]:
    section[0].reverse()
    section[1].reverse()
    section[2].reverse()
    section[3].reverse()
# 좌우반전
if result[1]:
    section[0] = [row[::-1] for row in section[0]]
    section[1] = [row[::-1] for row in section[1]]
    section[2] = [row[::-1] for row in section[2]]
    section[3] = [row[::-1] for row in section[3]]

for _ in range(result[2]):
    section[0] = rotate(section[0])
    section[1] = rotate(section[1])
    section[2] = rotate(section[2])
    section[3] = rotate(section[3])
# 구간 1과 구간 2의 결과를 이어 붙이기
top_result = []
for row in range(len(section[List[0][0]])):
    # 각 행을 이어붙여서 새로운 리스트에 저장
    top_result.append(section[List[0][0]][row] + section[List[0][1]][row])
# 구간 3과 구간 4의 결과를 이어 붙이기
bottom_result = []
for row in range(len(section[List[1][0]])):
    # 각 행을 이어붙여서 새로운 리스트에 저장
    bottom_result.append(section[List[1][0]][row] + section[List[1][1]][row])
total_result = top_result + bottom_result

for i in total_result:
    print(*i)

 

 

처음 List가 처음 위치이다

나는

0 ㅣ 1

-------

3 ㅣ 2

 

이렇게 몇사분면인지 나타내는것을 List에 담아뒀고

result에 [상하반전여부, 좌우반전여부, 회전방향]

 

을 넣어 나중에 한 번에 처리해 주려고 했다.

 

근데 만약 90도를 옮기고 좌우반전을 하게되면 처음 그림에서 상하 반전과 같다. 그것을 체크해줘야한다.

 

 

반응형

댓글