[Algorithm] 곳감 (모래시계)

myeonji·2022년 1월 23일
0

Algorithm

목록 보기
13/89

현수는 곳감을 만들기 위해 감을 깍아 마당에 말리고 있습니다. 현수의 마당은 N*N 격자판으로 이루어져 있으며, 현수는 각 격자단위로 말리는 감의 수를 정합니다. 그런데 해의 위치에 따라 특정위치의 감은 잘 마르지 않습니다. 그래서 현수는 격자의 행을 기준으로 왼쪽, 또는 오른쪽으로 회전시켜 위치를 변경해 모든 감이 잘 마르게 합니다. 만약 회전명령 정보가 2 0 3이면 2번째 행을 왼쪽으로 3만큼 아래 그림처럼 회전시키는 명령입니다. 첫 번째 수는 행번호, 두 번째 수는 방향인데 0이면 왼쪽, 1이면 오른쪽이고, 세 번째 수는 회전하는 격자의 수입니다. M개의 회전명령을 실행하고 난 후 아래와 같이 마당의 모래시계 모양의 영역에는 감 이 총 몇 개가 있는지 출력하는 프로그램을 작성하세요.

회전명령에서 막혔다. 왼쪽으로 회전을 어떻게 시키지? 3번 회전 시켜야 하면 인덱스 하나하나 접근해서 왼쪽으로 하나씩 옮기는 건가.. temp에 값 미리 넣어놓고 뭐 그렇게 해야하나.. 하면서 어찌저찌 코드 짰다.. 나오는 리스트는 맞았지만 마지막에 합을 구하는 방법을 틀렸다.

<내 답안>

n = int(input())
nlist = [list(map(int, input().split())) for _ in range(n)]
m = int(input())
mlist = [list(map(int, input().split())) for _ in range(m)]

for i in range(m):
    if mlist[i][1] == 0:
        for j in range(mlist[i][2]):
            temp = nlist[mlist[i][0]-1][0]
            for k in range(1, n):
                nlist[mlist[i][0]-1][k-1] = nlist[mlist[i][0]-1][k]
            nlist[mlist[i][0]-1][n-1] = temp
    elif mlist[i][1] == 1:
        for j in range(mlist[i][2]):
            temp = nlist[mlist[i][0]-1][n-1]
            for k in range(n-1, 0, -1):
                nlist[mlist[i][0]-1][k] = nlist[mlist[i][0]-1][k-1]
            nlist[mlist[i][0]-1][0] = temp

s = 0
e = n-1
sum = 0

for i in range(n):
        for j in range(s, e+1):
            sum += nlist[i][j]
        if s < n//2:
            s += 1
            e -= 1
        else:
            s -= 1
            e += 1

print(sum)

<모범답안>

n = int(input())
a = [list(map(int, input().split())) for _ in range(n)]
m = int(input())

for i in range(m):
    h, t, k = map(int, input().split())

    if t == 0:  # 왼쪽
        for _ in range(k):
            a[h-1].append(a[h-1].pop(0))  # 0번 인덱스 꺼내서 맨 뒤로 넣기. 나머지 데이터는 빈자리 채우러 앞으로 땡겨지기 때문.
    elif t == 1:  # 오른쪽
        for _ in range(k):
            a[h - 1].insert(0, a[h - 1].pop())

s = 0
e = n-1
sum = 0

for i in range(n):
    for j in range(s, e+1):
        sum += a[i][j]
    if i < n//2:
        s += 1
        e -= 1
    else:
        s -= 1
        e += 1

print(sum)

해설을 듣고 이 문제의 방식을 깨달았다.
왼쪽으로 회전시키는 것은 생각보다 간단했다.
12 39 30 23 11 이러한 행을 왼쪽으로 3번 회전시킨다고 하면, 39 30 23 11 12 다음 30 23 11 12 39 다음 23 11 12 39 30 하면 된 것이다. 앞에 3개 숫자를 맨 뒤로 하나씩 보내면 됐다.. 내가 숫자를 바꿔야 한다는 생각에만 갇혀서 그런가 이러한 방식은 생각 못했다. 기억해둬야겠다.

만약 인덱스 0에서 pop()을 사용하면 나머지 뒤의 데이터들은 자동으로 앞으로 한 칸씩 온다. (나는 pop()을 사용하지 않고 모든 인덱스를 하나하나 앞으로 땡겼다..) 그 다음에 pop한 값을 맨 뒤에 append를 하면 한 번의 회전이 일어난 것이다.

마지막에 모래시계 모양으로 합을 구하는 것은 사과나무 문제랑 비슷해서 응용해서 풀었는데 이 부분을 틀렸다.
조건문에서 i와 s 하나 차이였다. s가 틀린 이유를 몰랐는데 출력해보니 s가 작아지면 다시 if문이 참이 되므로 틀린 거였다. 해설 보니 그다지 어렵지 않은 것 같은데.. 내가 너무 어렵게 생각해서 푼 것 같다. 그리고 pop()!!! 이런 함수들 좀 잘 사용하고 싶다

0개의 댓글