카테고리 없음

[Baekjoon] 2659번 - 십자카드 문제 (java)

dongkii 2024. 6. 4. 11:58

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

조건 체크

  1. 주어지는 숫자는 0을 제외한 1 ~ 9
  2. 1121가 포함된 십자카드의 시계수는 1112

풀이

시계수의 최소값은 1이 네개인 1111이고, 최대값은 9가 네개인 9999이다. 그러므로, boolean 배열을 만들어 네자리수의 값이 시계수 일 때, true를 넣고, 중복되는 값을 체크하기 위해 map을 사용했다.
예를들어 1112의 값은 1112, 1121, 1211, 2111 중 최소값인 1112만 시계수이기 때문에 boolean[1112] = true 이고, 네개의 값 모두 map에 put한다.
위와 같이 1111부터 9999까지 브루트포스를 이용해 시계수 값만 true로 변경해주고, true 값이 몇번째에 나오는지 확인하면 된다.

소스코드

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

public class _2659 {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = null;

        int t = Integer.parseInt(bf.readLine().replaceAll(" ", ""));
        int tmin = t;
        for(int i = 0; i < 3; i++) {
            t = t/10 + t%10*1000;     // 한쪽방향으로만 회전
            tmin = Math.min(tmin, t); // 최소값이 시계수
        }

        Map<Integer, Integer> map = new HashMap<>();
        boolean[] chk = new boolean[10000];
        int cnt = 0;

        for(int i = 1111; i <= tmin; i++) { // 시계수의 최소값인 1111부터 주어진 십자카드의 시계수까지만 반복
            if(String.valueOf(i).contains("0") || map.get(i) != null) { 
                // 0은 십자카드에서 나올 수 없는 값이고,
                // 맵에 등록된 값이면 이미 중복된 값이기 때문에 continue
                continue;
            }

            int min = i;
            int a = i;
            for(int j = 0; j < 4; j++) {
                if(map.get(a) == null) {  // 맵에 없는 값 일 경우에만 등록
                    map.put(a, 1);
                }

                a = a/10 + a%10*1000;     // 한쪽방향으로 회전
                min = Math.min(min, a);      // 최소값(시계수)를 찾기 위함
            }

            chk[min] = true;             // 시계수일 경우에만 true
            cnt++;                        // 몇번째 시계수인지 체크
        }

        bw.write(cnt + "\n");

        bw.flush();
        bw.close();
    }
}