알고리즘/백준

백준 17822 : 원판돌리기(java)

우리로 2020. 9. 1. 12:26

https://www.acmicpc.net/problem/17822

 

17822번: 원판 돌리기

반지름이 1, 2, ..., N인 원판이 크기가 작아지는 순으로 바닥에 놓여있고, 원판의 중심은 모두 같다. 원판의 반지름이 i이면, 그 원판을 i번째 원판이라고 한다. 각각의 원판에는 M개의 정수가 적혀

www.acmicpc.net

로직 구성은 예전에 끝냈는데, java가 익숙치않아서 한참걸렸다...

 

단순 구현문제!

 

import java.io.*;
import java.util.*;

class Pair {
    int x, d, k;

    Pair(int a, int b, int c) {
        x = a;
        d = b;
        k = c;
    }
}

public class boj17822 {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static StringTokenizer st;

    static long N, M, T, answer = 0;
    static long[][] circle;
    static Pair[] circular;

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

        input();
        solve();
        bw.write("" + answer);
        bw.flush();
    }

    static long pL(String s) {
        return Long.parseLong(s);
    }

    static int pI(String s) {
        return Integer.parseInt(s);
    }

    static void input() throws IOException {
        st = new StringTokenizer(br.readLine(), " ");
        N = pL(st.nextToken());
        M = pL(st.nextToken());
        T = pL(st.nextToken());

        circle = new long[(int) N + 1][(int) M];
        for (int i = 1; i <= N; i++) {
            st = new StringTokenizer(br.readLine(), " ");
            for (int j = 0; j < M; j++) {
                circle[i][j] = pL(st.nextToken());
            }
        }

        circular = new Pair[(int) T];
        for (int i = 0; i < T; i++) {
            st = new StringTokenizer(br.readLine(), " ");
            int a, b, c;
            a = pI(st.nextToken());
            b = pI(st.nextToken());
            c = pI(st.nextToken());

            circular[i] = new Pair(a, b, c);
        }
    }

    static void rotate(int t) {
        // circular[t] Operation

        // k는 회전 횟수
        for (int multi = 1; multi * circular[t].x <= N; multi++) {
            int currCircle = circular[t].x * multi;

            for (int cnt = 0; cnt < circular[t].k; cnt++) {
                // 시계방향
                if (circular[t].d == 0) {
                    long temp = circle[currCircle][(int) M - 1];
                    for (int i = (int) M - 1; i > 0; i--)
                        circle[currCircle][i] = circle[currCircle][i - 1];

                    circle[currCircle][0] = temp;
                }
                // 반 시계 방향
                else {
                    long temp = circle[currCircle][0];
                    for (int i = 0; i < M - 1; i++)
                        circle[currCircle][i] = circle[currCircle][i + 1];

                    circle[currCircle][(int) M - 1] = temp;
                }
            }
        }
    }

    static long[][] deepCopy(long [][]src ){
        long[][] result = new long[(int)N + 1][(int)M];
        for(int i = 1; i <= N; i++){
            System.arraycopy(src[i], 0, result[i], 0, src[i].length);
        }
        return result;
    }

    static void solve() throws IOException {

        for (int t = 0; t < T; t++) {
            // Rotate
            boolean flag = true;

            rotate(t);
            long[][] temp = deepCopy(circle);

            long summation = 0;

            for (int i = 1; i <= N; i++) {
                for (int j = 1; j < M; j++) {
                    // 인접했는데 같은 숫자는 다 지운다.
                    if(circle[i][0] != 0 && circle[i][0] == circle[i][(int)M-1]){
                        flag = false;
                        temp[i][0] = temp[i][(int)M-1] = 0;
                    }
                    if (circle[i][j] != 0 && circle[i][j] == circle[i][j - 1]) {
                        flag = false;
                        temp[i][j] = temp[i][j-1] = 0;
                    }
                }
            }

            for (int i = 0; i < M; i++) {
                for (int j = 1; j <= N; j++) {
                    if (circle[j][i] != 0 && (circle[j][i] == circle[j - 1][i])) {
                        flag = false;
                        temp[j][i] = temp[j - 1][i] = 0;
                    }
                }
            }

            // 인접한 수가 없으므로 평균에 더해줘야함
            if(flag == true){
                int cnt = 0;
                for(int i = 1; i <= N; i++){
                    for(int j = 0; j < M; j++){
                        if(temp[i][j] != 0) cnt++;
                        summation += temp[i][j];
                    }
                }
                // 평균을 구했다.
                double avg = (double)summation / cnt;
                for(int i = 1; i <= N; i++){
                    for(int j = 0; j < M; j++){
                        if(temp[i][j] != 0){
                            if(temp[i][j] > avg){
                                temp[i][j] --;
                            } else if(temp[i][j] < avg){
                              temp[i][j] ++;
                            }
                        }
                    }
                }
            }
            circle = deepCopy(temp);

        }

        for (int i = 1; i <= N; i++) {
            for (int j = 0; j < M; j++) {
                answer += circle[i][j];
            }
        }
    }
}