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도를 옮기고 좌우반전을 하게되면 처음 그림에서 상하 반전과 같다. 그것을 체크해줘야한다.
반응형
댓글