Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

14-mj111 #223

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

14-mj111 #223

wants to merge 1 commit into from

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
Collaborator

@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

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.

3 participants