Skip to content

Conversation

@mjj111
Copy link
Collaborator

@mjj111 mjj111 commented Sep 9, 2024

πŸ”— 문제 링크

λ°±μ€€ - μ›νŒ 돌리기
https://www.acmicpc.net/problem/17822

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

1μ‹œκ°„

✨ μˆ˜λ„ μ½”λ“œ

ν•΄λ‹Ή λ¬Έμ œλŠ”,
μ£Όμ–΄μ§„ μ›νŒμ—μ„œ νšŒμ „μ‹œν‚€κ³ , μΈμ ‘ν•œ 점수끼리 μ—†μ• λ˜μ§€,
νšŒμ „ μ‹œν‚€κ³ , μΈμ ‘ν•œ μ μˆ˜κ°€ μ—†μœΌλ©΄ ν‰κ· μœΌλ‘œ μΉ˜ν™˜ν•˜λ©°
μ΅œμ’… μ›νŒμ—μ„œ 적힌 점수의 합을 좜λ ₯ν•˜λŠ” λ¬Έμ œμž…λ‹ˆλ‹€.

λ¨Όμ € μ›νŒ μ μˆ˜λ“€μ„ μž…λ ₯λ°›μŠ΅λ‹ˆλ‹€.

        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        T = Integer.parseInt(st.nextToken());

        arr = new int[N+1][M];

        for(int i=1; i<=N; ++i) {
            st = new StringTokenizer(br.readLine());
            for(int j=0; j<M; ++j) {
                arr[i][j] = Integer.parseInt(st.nextToken());
            }
        }
 

이후 μ£Όμ–΄μ§„ 값에 따라 νšŒμ „μ„ μ‹œμΌœμ€λ‹ˆλ‹€.

        int remainCnt = N*M;
        for(int i=0; i<T; ++i) {
            st = new StringTokenizer(br.readLine());
            int x = Integer.parseInt(st.nextToken());
            int d = Integer.parseInt(st.nextToken());
            int k = Integer.parseInt(st.nextToken());

            // νšŒμ „ μ‹œν‚€κΈ°
            for(int r=x; r<=N; r+=x) {
                arr[r] = rotate(r, d, k);
            }

νšŒμ „νŒμ—μ„œ 아직 μˆ«μžκ°€ λ‚¨μ•„μž‡λŠ”μ§€ ν™•μΈν•©λ‹ˆλ‹€.
λ§Œμ•½ μˆ«μžκ°€ λ‚¨μ•„μžˆκ³ ,
μΈμ ‘ν•œ 같은 μˆ«μžκ°€ μ‘΄μž¬ν•œλ‹€λ©΄ 0으둜 λ§Œλ“€μ–΄μ€λ‹ˆλ‹€.

            // μˆ˜κ°€ λ‚¨μ•„μžˆλŠ”μ§€ ν™•μΈν•˜κΈ°
            if(remainCnt > 0) {
                zeroNum = 0;
                total = 0;
                cnt = 0;
                boolean[][] zero = makeZero(arr);

λ§Œμ•½ λ§Œμ•½ μˆ«μžκ°€ λ‚¨μ•„μžˆκ³ ,
μΈμ ‘ν•œ 같은 μˆ«μžκ°€ μ—†λ‹€λ©΄ ν‰κ· κ°’μœΌλ‘œ μΉ˜ν™˜ν•΄ μ€λ‹ˆλ‹€.

                if(zeroNum == 0) {
                    double avg = (double)total / (double)cnt;

                    for(int r=1; r<=N; ++r) {
                        for(int c=0; c<M; ++c) {
                            if(arr[r][c] == 0) continue;
                            if((double)arr[r][c] < avg) arr[r][c]++;
                            else if((double)arr[r][c] > avg) arr[r][c]--;
                        }
                    }
                }
                else {
                    for(int r=1; r<=N; ++r) {
                        for (int c = 0; c < M; ++c) {
                            if(zero[r][c]) arr[r][c] = 0;
                        }
                    }

                }
            }
        }

μ£Όμ–΄μ§„ νšŒμ „μ„ λ‹€ 마쳀으면, νšŒμ „νŒμ— μžˆλŠ” μˆ«μžλ“€μ˜ 합을 좜λ ₯ν•΄μ€λ‹ˆλ‹€.

        int ans = 0;
        for(int r=1; r<=N; ++r) {
            for(int c=0; c<M; ++c) {
                ans += arr[r][c];
            }
        }

        System.out.println(ans);
    }

μ›νŒμ˜ 숫자λ₯Ό λŒλ¦¬λŠ” 방법은 κ°„λ‹¨ν•©λ‹ˆλ‹€.
μ£Όμ–΄μ§„ μ‹œκ³„λ°©ν–₯에 맞좰 μ£Όμ–΄μ§„ 만큼 μ΄λ™μ‹œν‚΅λ‹ˆλ‹€.

    static int[] rotate(int r, int d, int k) {
        int[] newArr = new int[M];
        if(d == 0) { // μ‹œκ³„λ°©ν–₯
            for(int i=0; i<M; ++i) {
                newArr[i] = arr[r][(i+M-k) % M];
            }
        } else {
            for(int i=0; i<M; ++i) {
                newArr[i] = arr[r][(i+k) % M];
            }
        }

        return newArr;
    }

μΈμ ‘ν•œ 숫자λ₯Ό μ°Ύμ•„ 0으둜 λ§Œλ“œλŠ” μž‘μ—…μ€
μ—΄μ—μ„œ λ¨Όμ € 인접을 ν™•μΈν•˜κ³ , 이후 ν–‰μ—μ„œ 인접을 ν™•μΈν•˜μ—¬ 0으둜 μΉ˜ν™˜ν•΄μ£Όλ©΄ λ©λ‹ˆλ‹€.

    static boolean[][] makeZero(int[][] arr) {
        boolean[][] zero = new boolean[N+1][M];
        for(int i=1; i<=N; ++i) {
            for(int j=0; j<M; ++j) {
                if(arr[i][j] == 0) continue;

                cnt++;
                total += arr[i][j];

                if(arr[i][j] == arr[i][(j+1)%M]) {
                    zero[i][j] = zero[i][(j+1)%M] = true;
                    zeroNum++;
                }

                if(i<N && arr[i][j] == arr[i+1][j]) {
                    zero[i][j] = zero[i+1][j] = true;
                    zeroNum++;

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

λΉ‘κ΅¬ν˜„μ—μ„œ μ£Όμ–΄μ§„ μˆœμ„œλŒ€λ‘œ μ°¨κ·Όμ°¨κ·Ό κ΅¬ν˜„ν•  λ•Œ
메인 λ©”μ„œλ“œμ—μ„œ 일단 μž„μ˜μ˜ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ„λ‘ ν•˜κ³ λ‚˜μ„œ 이후에 μžμ„Έν•œ κ΅¬ν˜„μ„ ν•˜λŠ” λ°©μ‹μœΌλ‘œ ν•˜λŠ”κ²Œ κ°€μž₯ λΉ λ₯Έ 방법인 것 κ°™μŠ΅λ‹ˆλ‹€.

Copy link
Member

@gjsk132 gjsk132 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μΈμ ‘ν•œ 값이 μžˆμ—ˆλŠ”μ§€ μ—†μ—ˆλŠ”μ§€ ν™•μΈν•˜λŠ” 과정을 boolean으둜 μ²˜λ¦¬ν•˜λ €ν–ˆλŠ”λ°...
λ§ˆμ§€λ§‰ μ˜ˆμ œμ—μ„œ μ μš©λ˜μ§€ μ•ŠλŠ” 뢀뢄이 μƒκ²¨μ„œ, κ·Έλƒ₯ zero_cnt(zeroNum)을 λ§Œλ“€μ–΄μ„œ ν•΄μ£Όλ‹ˆκΉŒ λ°”λ‘œ ν†΅κ³ΌλμŠ΅λ‹ˆλ‹€!

전체 μ½”λ“œ

import sys
sys.setrecursionlimit(100000)
input = open("input.txt").readline

N, M, T = map(int, input().split())

target = [list(map(int,input().split())) for _ in range(N)]

offset = [(1, 0), (0,1), (-1,0), (0,-1)]

for _ in range(T):

    # 돌리기
    disk, dir, cnt = map(int,input().split())
    cnt = cnt if dir else M-cnt

    for i in range(disk, N+1, disk):
        target[i-1] = target[i-1][cnt:] + target[i-1][:cnt]

    # 인접 μ—†μ• κΈ°
    
    def dfs(x, y, num):
        
        zero_cnt = 0

        for dx, dy in offset:

            nx = x + dx
            ny = (y + dy + M)%M
            
            if nx < 0 or nx == N or target[nx][ny] == 0:
                continue

            if target[nx][ny] == num:
                
                if not target[x][y]:
                    zero_cnt += 1

                zero_cnt += 1
                target[x][y] = 0
                target[nx][ny] = 0
                zero_cnt += dfs(nx, ny, num)

        return zero_cnt


    zero_cnt = 0

    for i in range(N):

        for j in range(M):
            if not target[i][j] == 0:
                zero_cnt += dfs(i, j, target[i][j])
                
    # 인접 없을 μ‹œ, ν‰κ· ν•΄μ„œ κ°’ λ³€κ²½ν•˜κΈ°
    if not zero_cnt:

        left_cnt = sum([sum([0 if j==0 else 1 for j in i])for i in target])
        
        if not left_cnt:
            break
        
        total = sum([sum(i) for i in target]) / left_cnt

        for k1, v1 in enumerate(target):
            for k2, v2 in enumerate(v1):
                if 0 < v2 < total:
                    target[k1][k2] += 1
                elif v2 > total:
                    target[k1][k2] -= 1

print(sum([sum(i) for i in target]))

Copy link
Member

@9kyo-hwang 9kyo-hwang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μ „ ν’€λ‹€κ°€ μ •μ‹  λ‚˜κ°€μ„œ PR 보고 λ‹€ κ°ˆμ•„μ—Žμ—ˆλŠ”λ°λ„ 톡과가 μ•ˆλ˜λ„€μš” γ…Ž...
μ‘°λ§Œκ°„ λ‹€μ‹œ νŠΈλΌμ΄ν•΄λ³΄κ² μλ‹ˆλ‹€....
image

@9kyo-hwang 9kyo-hwang merged commit 41f9922 into main Apr 30, 2025
2 checks passed
@9kyo-hwang 9kyo-hwang deleted the 14-mjj111 branch April 30, 2025 06:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants