[문제풀이-백준] 17822. 원판 돌리기

Sjin·2021년 4월 29일
0

삼성 기출

목록 보기
15/20

원판 돌리기

아이디어

  • 원판을 원형 리스트로 바꿔 생각

구현 방법

  • 원판 돌리기(rotate)
    • Temp_keep에는 다음거를 덮어씌우기 전에 미리 저장
    • Temp_pull에 담겨져 있는 값으로 덮어 씌움
    • Temp_pull에는 temp_keep의 값을 넣어줌
  • 같은 값이 있는지 확인(check)
    • 같은 값이 존재하면 temp_matrix에 표시
      • 같은 값 여러개가 이어져 있을 경우에 대비하기 위해
    • 같은 값이 존재한다면 isSame에 표시
      • 향후 같은 값이 존재하지 않을 경우엔 평균 값 계산 후 원판에 있는 값을 바꾸기 위해

예상치 못한 오류

  • 런타임 에러
    • Calculate 함수에서 cnt가 0인 경우 분모가 0인 상태로 나누게 되므로 런타임 에러
      • cnt가 0이란 말은 모두 지워졌단 뜻인데, 처음엔 모두 지워졌으면 같은 숫자가 없으므로 calculate함수가 실행 되지 않는다고 생각하였음
      • 하지만, 모두 지워진 상태에서 아직 회전을 다 못했다면, 더 회전하고 같은 숫자가 없으므로 calculate함수 실행된다. 이때, cnt가 0이 되므로 런타임 에러 발생
      • 평균을 구하기 전, cnt가 0이라면 즉시 리턴
        • 어차피 cnt가 0이면 모두 지워져있는 상태이므로 더이상 건드릴 필요 없음
  • 문제 해석 오류
    • 회전이 끝날때마다 체크하여 인접한 수가 없으면 평균을 구해서 값을 바꿔야 한다.
      • 이를 잘못 이해하여 회전이 모두 끝나고 평균 값 구해서 계산하고 그 값들을 더하여 답을 구했음

어려웠던 점

  • 자바로 구현할 때 음수를 양수로 나눈 나머지를 구하면 답이 음수가 나옴
    • ex) -1 % 2 => python에선 1, java에선 -1

코드

  • python
def rotate(i, dir, count):
    for cnt in range(count):
        temp_pull = matrix[i][0]
        nj = 0
        for j in range(M):
            nj = (nj+direct[dir]) % M
            temp_keep = matrix[i][nj]
            matrix[i][nj] = temp_pull
            temp_pull = temp_keep


def check():
    isSame = False
    for i in range(N):
        for j in range(M):
            nj = (j+1)%M
            if matrix[i][j] and (matrix[i][j] == matrix[i][nj]):
                isSame = True
                temp_matrix[i][j] = -1
                temp_matrix[i][nj] = -1

    for j in range(M):
        for i in range(N-1):
            if matrix[i][j] and matrix[i][j] == matrix[i+1][j]:
                isSame = True
                temp_matrix[i][j] = -1
                temp_matrix[i+1][j] = -1

    for i in range(N):
        for j in range(M):
            if temp_matrix[i][j] == -1:
                matrix[i][j] = 0
                temp_matrix[i][j] = -1
    if isSame:
        return True
    else:
        return False


def calculate(cnt):
    sum = 0
    for i in range(N):
        for j in range(M):
            if matrix[i][j]:
                cnt += 1
                sum += matrix[i][j]
    if not cnt:
        return
    avg = sum / cnt
    for i in range(N):
        for j in range(M):
            if matrix[i][j]:
                if matrix[i][j] > avg:
                    matrix[i][j] -= 1
                elif matrix[i][j] < avg:
                    matrix[i][j] += 1


N, M, T = map(int, input().split())
direct = [1, -1]
matrix = [list(map(int, input().split())) for _ in range(N)]
rotate_data = [list(map(int, input().split())) for _ in range(T)]
for t in range(T):
    x, d, k = rotate_data[t][0], rotate_data[t][1], rotate_data[t][2]
    for num in range(1, N+1):
        if num % x == 0:
            rotate(num-1, d, k)
    temp_matrix = [[0] * M for _ in range(N)]
    if not check():
        calculate(0)
result = 0
for i in range(N):
    for j in range(M):
        if matrix[i][j]:
            result += matrix[i][j]
print(result)
  • java
import java.util.*;
import java.io.*;

public class Main {
	static int N, M, T;
	static int[] direct = {
			1, -1
	};
	static int[][] matrix;
	static int[][] rotateData;
	
	public static void rotate(int idx, int dir, int count) {
		int tempPull, tempKeep, nj;
		for (int cnt=0; cnt<count; cnt++) {
			tempPull = matrix[idx][0];
			if (dir == 1) {
				nj = M;
			} else {
				nj = 0;
			}
			for (int j=0; j<M; j++) {
				nj = (nj+direct[dir]) % M;
				tempKeep = matrix[idx][nj];
				matrix[idx][nj] = tempPull;
				tempPull = tempKeep;
 			}
		}
	}
	
	public static boolean check() {
		boolean isSame = false;
		int nj;
		int[][] tempMatrix = new int[N][M];
		for (int i=0; i<N; i++) {
			for (int j=0; j<M; j++) {
				nj = (j+1) % M;
				if (matrix[i][j] > 0 && (matrix[i][j] == matrix[i][nj])) {
					isSame = true;
					tempMatrix[i][j] = -1;
					tempMatrix[i][nj] = -1;
				}
			}
		}
		for (int j=0; j<M; j++) {
			for (int i=0; i<N-1; i++) {
				if (matrix[i][j] > 0 && (matrix[i][j] == matrix[i+1][j])) {
					isSame = true;
					tempMatrix[i][j] = -1;
					tempMatrix[i+1][j] = -1;
				}
			}
		}
		for (int i=0; i<N; i++) {
			for (int j=0; j<M; j++) {
				if (tempMatrix[i][j] == -1) {
					matrix[i][j] = 0;
				}
			}
		}
		if (isSame) {
			return true;
		} else {
			return false;
		}
	}
	
	public static void calculate(int cnt) {
		int sum = 0;
		double avg = 0;
		for (int i=0; i<N; i++) {
			for (int j=0; j<M; j++) {
				if (matrix[i][j] > 0) {
					cnt ++;
					sum += matrix[i][j];
				}
			}
		}
		if (cnt != 0) {
			avg = (double)sum / (double)cnt;
			for (int i=0; i<N; i++) {
				for (int j=0; j<M; j++) {
					if (matrix[i][j] > 0) {
						if (matrix[i][j] > avg) {
							matrix[i][j] --;
						} else if (matrix[i][j] < avg) {
							matrix[i][j] ++;
						}
					}
				}
			}
		}
	}
	
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		int x, d, k;
		int result = 0;
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		T = Integer.parseInt(st.nextToken());
		matrix = new int[N][M];
		for (int i=0; i<N; i++) {
			st = new StringTokenizer(br.readLine(), " ");
			for (int j=0; j<M; j++) {
				matrix[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		rotateData = new int[T][3];
		for (int i=0; i<T; i++) {
			st = new StringTokenizer(br.readLine(), " ");
			rotateData[i][0] = Integer.parseInt(st.nextToken());
			rotateData[i][1] = Integer.parseInt(st.nextToken());
			rotateData[i][2] = Integer.parseInt(st.nextToken());
		}

		for (int t=0; t<T; t++) {
			x = rotateData[t][0];
			d = rotateData[t][1];
			k = rotateData[t][2];
			for (int num=1; num<N+1; num++) {
				if (num % x == 0) {
					rotate(num-1, d, k);
				}
			}
			if (!check()) {
				calculate(0);
			}					
		}
		
		for (int i=0; i<N; i++) {
			for (int j=0; j<M; j++) {
				if (matrix[i][j] > 0) {
					result += matrix[i][j];
				}
			}
		}
		System.out.println(result);

	}

}
profile
웹뷰 개발에 관심 많은 Front-end 개발자입니다.

0개의 댓글

관련 채용 정보