ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • boj)14391 - 종이 조각
    PS/boj 2020. 12. 9. 18:44
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    import java.io.*;
    import java.util.StringTokenizer;
     
    public class boj_14391 {
        static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        static StringTokenizer st;
        static int row, col, max;
        static int[][] map;
     
        public static void main(String[] args) throws IOException {
            st = new StringTokenizer(br.readLine());
            row = Integer.parseInt(st.nextToken());
            col = Integer.parseInt(st.nextToken());
            map = new int[row][col];
     
            for (int i = 0; i < row; i++) {
                String str = br.readLine();
                for (int j = 0; j < col; j++) {
                    map[i][j] = str.charAt(j) - '0';
                }
            }
     
            // 전부 순회
            // 0: 가로, 1 : 세로 
            for (int s = 0; s < (1<<(row * col)); s++) {
                // 가로에 대한 합
                int sum = 0;
                for (int i = 0; i < row; i++) {
                    int cur = 0;
                    for (int j = 0; j < col; j++) {
                        int k = i * col + j;
                        if ((s&(1<<k)) == 0) {
                            cur = cur * 10 + map[i][j];
                        } else {
                            sum += cur;
                            cur = 0;
                        }
                    }
                    sum += cur;
                }
                // 세로에 대한 합
                for (int j = 0; j < col; j++) {
                    int cur = 0;
                    for (int i = 0; i < row; i++) {
                        int k = i * col + j;
                        if ((s&(1<<k)) != 0) {
                            cur = cur * 10 + map[i][j];
                        } else {
                            sum += cur;
                            cur = 0;
                        }
                    }
                    sum += cur;
                }
                max = Math.max(max, sum);
            }
            System.out.println(max);
        }
    }
     
    cs

     

    - 브루트포스, 비트마스크

     

    - 어렵다.

    - 비트마스크로 접근해야겠다는 건 알겠는데 가로 세로 잘라서 합 구하는 거 구현에 실패했다.

     

    - 일단 문제 조건에서 N, M의 제한이 4로 작다.

    - 처음에는 N, M 중 길이가 긴 곳에서 시작해서 무조건 긴 거만 뽑으면 되지 않을까? 생각했는데 반례가 존재한다.

    - 예를 들어 n, m = 4, map =>

    0005

    0000    이러한 경우에 기존의 생각대로 답을 구하면 5005이지만

    0000    답은 5500이다 (5000) + (500)

    5000

     

    - 그러면 어떻게 접근할까?

    - 문제의 조건이 작으니까 전부 다 돌아보자라는 생각

    - 최대 16 개의 bit (4*4)로 나타낼 수 있는데 현재의 값이 가로인지? 세로인지?라는 생각으로 접근한다.

    - 그렇다면 0000,0000,0000,0000 ~ 1111,1111,1111,1111까지 최대 2^16번이니까 시간제한에 통과한다.

     

    - k = i * col + j인데 이것은 현재 몇 번째 칸에 있는지를 뜻하는 것이다.

     

    - 가로에 대한 합 

    - 0이라면 cur = cur * 10 + map [i][j], 1이라면 현재까지 만들어진 가로에 대한 합을 sum에 추가하고 cur 초기화

    - 현재 가로를 끝까지 다 돌았으면  sum += cur

    - 세로에 대한 합도 가로에 대한 합과 동일하게 구해주면 된다.

     

    - max = Math.max(max, sum)

     

     

     

     


    www.acmicpc.net/problem/14391

    'PS > boj' 카테고리의 다른 글

    boj)7562 - 나이트의 이동  (0) 2020.12.10
    boj)11723 - 집합  (0) 2020.12.09
    boj)2529 - 부등호  (0) 2020.12.08
    boj)15661 - 링크와 스타트  (0) 2020.12.06
    boj)14889 - 스타트와 링크  (0) 2020.12.03
킹수빈닷컴