[BAEK] 17822. 원판 돌리기
in Category / ProblemSolving
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);
}
}
}
}
}