이 문제는 시뮬 + bfs로 풀었습니다.
package sw;
import java.io.*;
import java.util.*;
public class Main17822_원판돌리기 {
static int N,M,T;
static int[][] map;
static int[][] dir = // 우하좌상
static boolean check(int x, int y) {
if(x>=0 && x<N && y>=0 && y<M)
return true;
else return false;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().trim().split(" ");
N = Integer.parseInt(input[0]);
M = Integer.parseInt(input[1]);
T = Integer.parseInt(input[2]);
map = new int[N][M];
String[] str = null;
for(int i=0; i<N; i++) {
str = br.readLine().trim().split(" ");
for(int j=0; j<M; j++) {
map[i][j] = Integer.parseInt(str[j]);
}
}
float avg=0;
int x,d,k;
for(int i=0; i<T; i++) {
str = br.readLine().trim().split(" ");
x = Integer.parseInt(str[0]);
d = Integer.parseInt(str[1]); // 0시계, 1반시계
k = Integer.parseInt(str[2]);
// 회전
for(int j=0; j<N; j++) { // x의 배수 라인을 d방향으로 k만큼 회전 회전
if((j+1)%x==0) {
rotate(j,d,k);
}
}
// 인접한 번호 지워주고, 지울게 없다면 평균값 계산하여 원판에 적용
avg = deleteAndAvg(); // 인접한게 있다면 -1, 없다면 평균값 준다.
if(avg != -1) { // 인접한게 없을 때 계산.
calc(avg);
}
}
System.out.println(result());
}
// 최종 원판에 남은 번호 계산.
static int result() {
int res=0;
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
if(map[i][j] != -1) {
res+=map[i][j];
}
}
}
return res;
}
// 평균값으로 원판 넘버에 적용. 이때 평균값은 소수자리까지 계산.
static void calc(float avg) {
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
if(map[i][j] != -1) {
if(map[i][j] > avg) map[i][j]-=1;
else if(map[i][j] < avg) map[i][j]+=1;
}
}
}
}
//회전
static void rotate(int x, int d, int k) {
int s=0;
int[] set = new int[M];
if(k % M == 0) return;
if(d==0) { // 시계방향
s = k % M;
}else if(d==1) { // 반시계 방향
s = M - k%M;
}
for(int i=0; i<M; i++) {
set[(s+i)%M] = map[x][i];
}
map[x] = set;
}
//인접한 넘버 지우고 평균값 계산.
static float deleteAndAvg() {
int num=0;
int sum=0;
int cnt=0;
int flag = 0;
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
if(map[i][j] != -1) {
num = bfs(i,j); // bfs로 인접한 넘버 지우기.
if(num == -1) { // 인접했다면
flag++;
} else {
sum += num; // 인접하지 않았다면 그 숫자 다 더해주기.
cnt++; // 평균값 내기위한 작업.
}
}
}
}
return flag>0?-1:(float)sum/cnt; // 인접한게 있다면 -1, 인접한게 없다면 avg 리턴
}
static int bfs(int x, int y) {
Queue<Pos> qu = new LinkedList<>();
qu.add(new Pos(x,y));
int num = map[x][y];
Pos p = null;
int dx,dy;
boolean flag = false;
while(!qu.isEmpty()) {
p = qu.poll();
for(int d=0; d<4; d++) {
dx = p.x + dir[d][0];
dy = p.y + dir[d][1];
dy = (M+dy)%M; // 좌우는 원형으로 비교.
if(check(dx,dy) && num == map[dx][dy]) {
qu.add(new Pos(dx, dy));
map[dx][dy] = -1;
flag = true;
}
}
}
if(flag) map[x][y] = -1;
return map[x][y];
}
static void print() {
System.out.println();
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++)
System.out.print(map[i][j]+" ");
System.out.println();
}
System.out.println("=====================");
}
static class Pos{
int x,y;
public Pos(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "[" + x + "," + y + "]";
}
}
}
PREVIOUS[삼성기출]백준17142 - 연구소3