[BAEK] 17822. 원판 돌리기

[BaekJoon] 17822번 원판 돌리기
삼성 기출문제

17822. 원판 돌리기

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

	static int N,M,T;
	static int[][] order;
	static int[][] wonpan;
	static int[][] dir = { {-1,0},{1,0},{0,-1},{0,1} };
	static boolean removePossible;
	static boolean removeNumber;
	static boolean[][] visited;
	static int result;

	public static void main(String[] args) throws Exception{

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		N = Integer.parseInt(st.nextToken()); // 원판 갯수
		M = Integer.parseInt(st.nextToken()); // 원판 안 번호 갯수
		T = Integer.parseInt(st.nextToken()); // 회전 명령
		wonpan = new int[N][M];
		order = new int[T][3];
		
		for(int i=0;i<N;i++) {
			st = new StringTokenizer(br.readLine());
			for(int j=0;j<M;j++) {
				wonpan[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		
		for(int i=0;i<T;i++) {
			st = new StringTokenizer(br.readLine());
			for(int j=0;j<3;j++) {
				order[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		
		for(int i=0;i<T;i++) {
			rotateWonpan(i);
			
			removeNumber = false;
			removeWonpanNumber();
			
			if(!removeNumber) {
				reviseWonpanNumber();
			}
		}
		
		for(int i=0;i<N;i++) {
			for(int j=0;j<M;j++) {
				result += wonpan[i][j];
			}
		}
		
		System.out.println(result);
	}
	
	public static void rotateWonpan(int curNum) {
		for(int i=order[curNum][0]-1;i<N;i++) {
			// 원판 번호가 배수에 해당
			if( (i+1) % order[curNum][0] == 0) {
				if(order[curNum][1]==0) {// 시계 방향					
					for(int j=0;j<order[curNum][2];j++) {
						int lastNum = wonpan[i][M-1];
						
						for(int k=M-2;k>=0;k--) {
							wonpan[i][k+1] = wonpan[i][k];
						}						
						
						wonpan[i][0] = lastNum;
					}
					
				}else { // 반시계 방향	
					for(int j=0;j<order[curNum][2];j++) {
						int firstNum = wonpan[i][0];
						
						for(int k=1;k<M;k++) {
							wonpan[i][k-1] = wonpan[i][k];
						}
						
						wonpan[i][M-1] = firstNum;
					}
				}
			}
		}
		
	}
	
	public static void removeWonpanNumber() {
		visited = new boolean[N][M];
		
		for(int i=0;i<N;i++) {
			for(int j=0;j<M;j++){
				removePossible = false;
				
				if(!visited[i][j]) {
					visited[i][j] = true;
					if(wonpan[i][j]!=0)
						checkNumber(i,j,wonpan[i][j]);
				}
				
				if(removePossible) {
					wonpan[i][j] = 0;
				}
			}
		}
	}
	
	public static void reviseWonpanNumber() {
		double total = 0;
		int count = 0;
		double avg = 0;
		
		for(int i=0;i<N;i++) {
			for(int j=0;j<M;j++) {
				total += wonpan[i][j];
				if(wonpan[i][j] != 0 ) {
					count++;
				}
			}
		}
		
		avg = total/count;
		
		for(int i=0;i<N;i++) {
			for(int j=0;j<M;j++) {
				if(wonpan[i][j]!=0 && wonpan[i][j]!=avg) {
					wonpan[i][j] = wonpan[i][j] < avg ? wonpan[i][j]+1 : wonpan[i][j]-1;
				}
			}
		}
		
	}
	
	public static void checkNumber(int y,int x,int curValue) {
		for(int i=0;i<dir.length;i++) {
			int dr = y + dir[i][0];
			int dc = x + dir[i][1];
			
			// 행만 검사
			if(dr>=0 && dr<N) {
				// 열은 순환되게 설정.
				if(dc == M) dc = 0;
				else if(dc == -1) dc = M-1;
				
				if(curValue == wonpan[dr][dc] && !visited[dr][dc]) {
					wonpan[dr][dc] = 0;
					visited[dr][dc]=true;
					removePossible = true;
					removeNumber = true;
					checkNumber(dr,dc,curValue);
				}
			}
		}
	}

}

© 2019. All rights reserved.

Powered by Hydejack v8.4.0