본문 바로가기
Algorithms/BOJ

[BOJ] 17822 원판 돌리기(Java)

by 그냥팬더 2021. 5. 1.
반응형

원판돌리기


삼성전자 2019 하반기 오후 1번 문제.

원판은 상하 좌우와 양끝이 인접하다.
(양끝 인접을 처리를 안해서 틀렸었다)

\1. 원판을 회전 시킨다.
\2. 인접하면서 같은 수를 찾는다
-a. 있으면 같은 수를 모두 지운다
-b. 없다면 원판의 평균을 구한 뒤 작으면 -1, 크면 +1

문제가 제시한 대로 구현하면 완료.

<전체소스>

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class problem17822 {

    private static int N, M, T, answer;
    private static int[][] operation, disk;
    private static int[] dr = {-1, 1, 0, 0};
    private static int[] dc = {0, 0, -1, 1};
    private static boolean isAdjcent;

    public static void main( String[] args ) throws IOException {
        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());
        disk = new int[N + 1][M];
        operation = new int[T][3];
        for (int i = 1; i < N + 1; i++) {
            st = new StringTokenizer(br.readLine(), " ");
            for (int j = 0; j < M; j++) {
                disk[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        for (int i = 0; i < T; i++) {
            st = new StringTokenizer(br.readLine(), " ");
            operation[i][0] = Integer.parseInt(st.nextToken());
            operation[i][1] = Integer.parseInt(st.nextToken());
            operation[i][2] = Integer.parseInt(st.nextToken());
        }

        int order = 0;
        while (T > 0) {
            isAdjcent = false;
            System.out.println(T);
            rotateDisk(order);
            T--;
            order++;
        }
        getSum();
        System.out.println(answer);
    }

    static void rotateDisk( int order ) {
        doOperation(order);
        for (int i = 1; i < N + 1; i++) {
            for (int j = 0; j < M; j++) {
                if (disk[i][j] != 0)
                    checkAdj(i, j);
            }
        }
        if (!isAdjcent) {
            editDisk();
        }
    }

    static void doOperation( int order ) {
        int diskNumber = operation[order][0];
        int direction = operation[order][1];
        int rotateCount = operation[order][2] % M;
        while (rotateCount > 0) {
            for (int i = diskNumber; i < N + 1; i += diskNumber) {
                if (direction == 0) {
                    int temp = disk[i][M - 1];
                    for (int index = M - 1; index > 0; index--) {
                        disk[i][index] = disk[i][index - 1];
                    }
                    disk[i][0] = temp;
                } else {
                    int temp = disk[i][0];
                    for (int index = 0; index < M - 1; index++) {
                        disk[i][index] = disk[i][index + 1];
                    }
                    disk[i][M - 1] = temp;
                }
            }
            rotateCount--;
        }
    }

    static void checkAdj( int r, int c ) {
        Queue<DiskInfo> q = new LinkedList<>();
        q.add(new DiskInfo(r, c, disk[r][c]));
        while (!q.isEmpty()) {

            DiskInfo now = q.poll();
            if (now.value != 0) {
                for (int i = 0; i < 4; i++) {

                    int nr = now.r + dr[i];
                    int nc = now.c + dc[i];

                    if (nr < 1 || nr > N) continue;
                    if (nc == -1) {
                        nc = M - 1;
                    } else if (nc == M) {
                        nc = 0;
                    }
                    if (disk[nr][nc] != 0 && now.value == disk[nr][nc]) {
                        disk[nr][nc] = 0;
                        q.add(new DiskInfo(nr, nc, now.value));
                        isAdjcent = true;
                    }
                }
            }
        }
    }

    static void editDisk() {
        int cnt = 0;
        int sum = 0;
        for (int r = 1; r < N + 1; r++) {
            for (int c = 0; c < M; c++) {
                if (disk[r][c] != 0) {
                    cnt++;
                    sum += disk[r][c];
                }
            }
        }
        double avg = (double) sum / cnt;
        for (int r = 1; r < N + 1; r++) {
            for (int c = 0; c < M; c++) {
                if (disk[r][c] != 0) {
                    if (disk[r][c] > avg)
                        disk[r][c]--;
                    else if (disk[r][c] < avg)
                        disk[r][c]++;
                }
            }
        }
    }

    static void getSum() {
        answer = 0;
        for (int i = 1; i < N + 1; i++) {
            for (int j = 0; j < M; j++) {
                answer += disk[i][j];
            }
        }
    }
}

class DiskInfo {
    int r;
    int c;
    int value;

    public DiskInfo( int r, int c, int value ) {
        this.r = r;
        this.c = c;
        this.value = value;
    }
}

[GitHub]

 

반응형

'Algorithms > BOJ' 카테고리의 다른 글

[BOJ] 17143 낚시왕(Java)  (0) 2021.05.01
[BOJ] 7576 토마토(Java)  (0) 2021.05.01

댓글