본문 바로가기

알고리즘 설계/내가 보려고 정리하는 문풀

곶감(모래시계)

곶감을 만들기 위해 감을 깎아 마당(그리드)에 말리고 있음

마당은 N*N 격자판으로 이루어져 있고 각 격자 단위에는 말리는 감의 수가 들어있음

해의 위치에 따라 특정 위치의 감은 잘 마르지 않으므로,

격자의 행을 기준으로 왼쪽, 또는 오른쪽으로 회전시켜 위치를 변경해야함

ex)회전 명령 정보가 2 0 3이면 2번째 행을 왼쪽(0)으로 3만큼 아래 그림처럼 회전시키는 명령임

2 0 3 예시

회전 명령의 첫 번째 수는 행 번호, 두 번째 수는 방향 (0 = 왼쪽, 1 = 오른쪽) 세 번째 수는 회전하는 격자의 수

M개의 회전 명령을 실행하고 난 후, 마당의 모래시계 영역에 있는 감의 총 개수를 출력하는 프로그램 작성

모래시계 모양

 

입력 예시)

5

10 13 10 12 15

12 39 30 23 11

11 25 50 53 15

19 27 29 37 27

19 13 30 13 19

3

2 0 3

5 1 2

3 1 4

 

출력 예시)

362


내가 쓴 코드

import sys
sys.stdin = open("input.txt", 'rt')

N = int(input())
grid = [list(map(int, input().split())) for _ in range(N)]
M = int(input())

for _ in range(M):
    toMove = [] #움직일 부분
    toStay = [] #가만히 있을 부분
    rowNum, direction, distance = map(int, input().split())

    #방향이 왼쪽인 경우, 움직일 부분은 뒤에 N-distance개
    if direction == 0:
        #움직일 부분 따로 넣어두고
        for i in range(distance,N):
            toMove.append(grid[rowNum-1][i])
        #가만히 있을 부분 따로 넣어두고
        for j in range(distance):
            toStay.append(grid[rowNum-1][j])
        #왼쪽으로 움직이니까 움직인 부분이 앞으로 옴
        grid[rowNum-1] = toMove + toStay

    #방향이 오른쪽인 경우, 움직일 부분은 앞에 N-distance개
    else:
        #움직일 부분 따로 넣어두고
        for i in range(N-distance):
            toMove.append(grid[rowNum-1][i])
        #가만히 있을 부분 따로 넣어두고
        for j in range(N-distance,N):
            toStay.append(grid[rowNum-1][j])
        #오른쪽으로 움직이니까 움직인 부분이 뒤로 옴
        grid[rowNum-1] = toStay + toMove

#모래시계 모양으로 수확하기
start = 0
end = N
total = 0

#모든 행을 돌건데
for i in range(N):
    #각 행의 컬럼의 시작과 끝까지 다 수확
    for j in range(start,end):
        total += grid[i][j]
    #가운데보다 위면 시작과 끝 범위를 줄여나감
    if i < N//2:
        start += 1
        end -= 1
    #가운데보다 아래면 시작과 끝 범위를 다시 늘림
    else:
        start -= 1
        end += 1

print(total)

 

모범답안

import sys
sys.stdin = open("input.txt", 'rt')

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))
    else:
        for _ in range(k):
            a[h-1].insert(0, a[h-1].pop())

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

 

모범답안 보고 느낀점

1. pop함수 쓰면 나머지 애들이 자동으로 앞으로 땡겨지는 것을 이용했구나

pop(0)했다가 다시 append하면 아주 단순하고 쉽게 회전할 있음

 

거꾸로 회전할 때는 pop() 했다가 0 index insert하면

단순하고 쉽게 구현 가능.

 

졸라 복잡하게 풀었네

 

2. 그래도 사과나무에서 배운 모래시계 수확 start랑 end는 잘 했네..

당연함 어제 한거니까..

잘했당~

 


 

다시 써보기

import sys
sys.stdin = open("input.txt" ,'rt')

N = int(input())
grid = [list(map(int, input().split())) for _ in range(N)]
M = int(input())

for _ in range(M):
    rowNum, direction, targets = map(int, input().split())
    if direction == 0:
        for i in range(targets):
            grid[rowNum-1].append(grid[rowNum - 1].pop(0))
    else:
        for i in range(targets):
            grid[rowNum-1].insert(0, grid[rowNum - 1].pop())

total = 0
s = 0
e = N

for i in range(N):
    for j in range(s, e):
        total += grid[i][j]
    if i < N//2:
        s += 1
        e -= 1
    else:
        s -= 1
        e += 1

print(total)

'알고리즘 설계 > 내가 보려고 정리하는 문풀' 카테고리의 다른 글

스도쿠 검사  (0) 2024.10.30
봉우리  (0) 2024.10.20
사과나무(다이아몬드)  (1) 2024.10.18
격자판 최대합  (3) 2024.10.16
수들의 합  (3) 2024.10.16