반응형
풀이
문제를 보면 원판이 있고, 문제도 길어서 어려워 보이지만,
사실 간단한 문제이다.
초기 값을 map에 입력 받고
1. 시계, 반시계 방향으로 몇 번 돌릴지
2. 인접한 숫자 중 같은 값이 있어주면 0으로 만들어주기
3. 인접한 숫자 중 같은 값이 없으면 평균 값을 구해 평균 값보다 크면 +1, 작으면 -1 해주는 문제
시계, 반시계는 forwardLotate(), reverseLotate()로 index를 하나씩 밀어주거나 땡겨주었다.
findEqualPoint()에서 bfs를 사용했는데, y값에 해당하는 값이 0 or M 값이 일때 조건을 줘 값을 바꿔주었다.
왜냐하면 원 형태이므로 순환하기 때문이다.
같은 값이 있으면 처리해서 point에 더해주었고
더한 point값 들을 total에서 빼주었다.
만약 point값이 0 이라면 onePlusMinus()에서 처리를 해주었다.
평균 값은 반올림을 하지 않으므로, float 타입으로 하여 평균값을 저장해주어 비교주었다.
import java.io.*;
import java.util.*;
public class Main {
static int N, M, T, x, d, k, total, point, count;
static int[][] map;
static Queue<int[]> queue = new LinkedList<int[]>();
static boolean[][] visited;
static int[] dx = {1,0,-1,0};
static int[] dy = {0,1,0,-1};
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());
count = N * M;
map = new int[N][M];
for(int i = 0 ; i < N ; i++) {
st = new StringTokenizer(br.readLine());
for(int j = 0 ; j < M ; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
total += map[i][j];
}
}
for(int i = 0 ; i < T ; i++) {
st = new StringTokenizer(br.readLine());
// x의 배수
x = Integer.parseInt(st.nextToken());
// 0 이면 시계 1 이면 반시계
d = Integer.parseInt(st.nextToken());
// k 칸
k = Integer.parseInt(st.nextToken());
for(int j = 0 ; j < k ; j++) {
if(d == 0) forwardLotate();
else if(d == 1) reverseLotate();
}
visited = new boolean[N][M];
point = 0;
for(int row = 0 ; row < N ; row++) {
for(int col = 0 ; col < M ; col++) {
if(map[row][col] == 0) visited[row][col] = true;
else if(visited[row][col] == false) findEqualPoint(row, col);
}
}
total -= point;
if(point == 0) onePlusMinus();
}
System.out.println(total);
}
private static void onePlusMinus() {
float average = (float)total / count;
for(int i = 0 ; i < N ; i++) {
for(int j = 0 ; j < M ; j++) {
if(map[i][j] == 0 ) continue;
else if(map[i][j] > average) {
map[i][j] -= 1;
total -= 1 ;
}
else if(map[i][j] < average) {
map[i][j] += 1;
total += 1;
}
}
}
}
private static void findEqualPoint(int x, int y) {
visited[x][y] = true;
queue.offer(new int[] {x, y});
int samePoint = 0;
int tmp = map[x][y];
while(!queue.isEmpty()) {
int[] cur = queue.poll();
for(int i = 0 ; i < 4 ; i++) {
int nx = cur[0] + dx[i];
int ny = cur[1] + dy[i];
if(0 > nx || nx >= N) continue;
if(0 > ny) ny = M-1;
if(ny >= M ) ny = 0;
if(visited[nx][ny]) continue;
if(map[nx][ny] == tmp) {
visited[nx][ny] = true;
queue.offer(new int[] {nx, ny});
samePoint += map[nx][ny];
count -= 1;
map[nx][ny] = 0;
}
}
}
if(samePoint > 0) {
map[x][y] = 0;
count -= 1;
samePoint += tmp;
}
point += samePoint;
}
private static void reverseLotate() {
int plus = x;
for(int i = x-1 ; i < N ; i += plus) {
int tmp = map[i][0];
for(int j = 0 ; j < M-1 ; j++) {
map[i][j] = map[i][j+1];
}
map[i][M-1] = tmp;
}
}
private static void forwardLotate() {
int plus = x ;
for(int i = x - 1; i < N ; i += plus) {
int tmp = map[i][M-1];
for(int j = M-1 ; j > 0 ; j--) {
map[i][j] = map[i][j-1];
}
map[i][0] = tmp;
}
}
}
반응형
'알고리즘 > 문제 풀이' 카테고리의 다른 글
[Java/자바 백준 10655] 마라톤 1 (0) | 2022.02.22 |
---|---|
[Java/자바 백준 17825] 주사위 윷놀이 (0) | 2022.02.17 |
[Java/자바 백준 17135] 캐슬 디펜스 (0) | 2022.02.15 |
[Java/자바 백준 1347] 미로 만들기 (0) | 2022.02.15 |
[Java/자바 백준 17837] 새로운 게임 2 (0) | 2022.02.14 |