문제풀이/백준

[백준]20444: 색종이와 가위 - JAVA

빈둥벤둥 2021. 7. 14. 15:07

[백준]20444: 색종이와 가위

 

20444번: 색종이와 가위

첫 줄에 정수 n, k가 주어진다. (1 ≤ n ≤ 231-1, 1 ≤ k ≤ 263-1)

www.acmicpc.net

풀이

🪑 색종이 컷트컷트 하는 문제로 이분탐색을 사용하는 문제였다!

 

사실 처음부터 이분탐색으로 풀어야겠다 하는 문제는 아니었다.

처음에는 n번으로 자를 수 있는 색종이의 개수를 백트랙킹으로 풀려고 생각했다가 N, K의 범위와 시간제한 0.1초인걸 보고 이분탐색이구나,, 했다.

 

이제 문제의 조건을 정리해보자.

  • 색종이는 직사각형이며 색종이를 자를 때는 한 변에 평행하도록 자른다.
  • 한 번에 한 경로의 모든 색종이를 다 자른다.
  • 이미 자른 곳은 또 자를 수 없다.

 

 

🔧 문제 풀이 순서를 생각해 보자.

  • N에 따른 K를 구할때, 가로로 자른 횟수와 세로로 자른 횟수에 따라 K값이 달라진다. 그러므로 가로로 몇 번 잘랐는지를 기준값으로 정해 이분탐색을 해 준다.
  • 이때 범위는 0 ~ N/2로 정한다. 가로로 자른 횟수와 세로로 자른 횟수가 바뀌어도 결과 값에는 영향이 없기 때문이다.

 

 

🔹 이분탐색을 한다.

- 나는 기준값을 가로로 자른 횟수를 설정해 주었다.

- 이때 세로로 자른 횟수도 구하여 이를 가지고 잘리는 색종이의 개수를 계산해 주었다.

- row, col일때 결과는 (row + 1) * (col + 1)이 나온다.

- 결과 값이 찾고자 하는 K와 같다면 YES를 출력해 주고 탐색을 끝낸다.

- 결과 값이 K보다 크다면 row, col의 차이를 더 크게하여 잘리는 색종이의 개수를 줄여준다.

- 결과 값이 K보다 작다면 row, col의 차이를 더 작게해 잘리는 색종이의 개수를 많아지게 한다.

 

코드

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
import java.util.*;
 
public class Main {
 
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
 
        long n = scan.nextInt();
        long k = scan.nextLong();
 
        long left = 0;
        long right = n / 2;
        while(left <= right) {
            long row = (left + right) / 2;
            long col = n - row;
 
            long total = cut_paper(row, col);
            if(total == k) {
                System.out.println("YES");
                return;
            } else if(total > k) { //row col의 차이가 더 커야한다.
                right = row - 1;
            } else if (total < k){
                left = row + 1;
            }  
        }
        System.out.println("NO");
    }
 
    public static long cut_paper(long row, long col) {
        return (row + 1* (col + 1);
    }
}
cs