kingsubin

boj)14391 - 종이 조각 본문

PS/boj

boj)14391 - 종이 조각

kingsubin 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
0 Comments
댓글쓰기 폼