백준 문제 풀이

BOJ 20444 색종이와 가위

david0506 2021. 2. 11. 10:53

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

 

20444번: 색종이와 가위

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

www.acmicpc.net

 

 

 

 

색종이를 $N$번 잘라서 $k$개의 조각으로 나눌 수 있는지 묻는 문제이다. 이 문제를 해결하는 방법으로 이분 탐색을 이용하는 방법, 이차방정식의 판별식을 이용하는 방법을 이용할 것이다. 먼저 이분탐색을 해결하는 방법을 설명하겠다.

색종이는 변에 평행하게 자를 수 밖에 없으므로 가로로 자르는 횟수를 $a$, 세로로 자르는 횟수를 $b$라고 하자.

그럼 가로로는 $a+1$개의 조각, 세로로는 $b+1$개의 조각으로 잘리므로 총 개수는 $(a+1)(b+1)$이다.

 

 

 

 

(3+1) X (2+1) = 12개의 조각이다.

 

 

 

그런데 $a+b=n$이므로 $b=n-a$, 따라서 총 개수는 $(a+1)(n-a+1)$이다. 이 식을 전개하면 이 값은 a에 대해 아래로 볼록한 이차함수의 형태가 되고 우리는 이 $a$에 대한 이차함수와 $y=k$와의 교점이 있는지 구하면 된다. 이차함수는 축을 기준으로 대칭이므로 0~$N$이 아닌 0~$N/2$ 사이의 구간만 탐색해도 된다.(탐색 범위가 0~$N$이여도 크게 상관은 없다.

 

 

 

 

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
#include <bits/stdc++.h>
 
using namespace std;
 
long long n, k;
 
int main()
{
    scanf("%lld %lld"&n, &k);
    long long s=0, e=n/2+1//e=n이여도 크게 상관 없다.
 
    while(s<=e){
        long long mid=+ e >> 1;
        long long res=(mid+1)*(n-mid+1);
        if(res==k){
            printf("YES\n");
            return 0;
        }
        else{
            if(s==e) break;
            if(res>k) e=mid-1;
            else s=mid+1;
        }
    }
    printf("NO\n");
    return 0;
}
cs

 

 

 

 

 

두 번째 방법으로 식 $(a+1)(n-a+1)$를 전개하면 $-a^{2}+na+n+1$이 되고 $-a^{2}+na+n+1 = k$에서  근의 공식을 이용해서 $a$가 양의 정수근을 가지는지 여부를 따지면 된다.

 

 

 

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
#include <iostream>
#include <cmath>
 
using namespace std;
 
typedef long long ll;
 
int main()
{
    long double n, m;
    scanf("%lf %lf"&n, &m);
    long double sq=sqrt(n*n+4*(n-m+1));
    //근의 공식에서 √(b^2-4ac)가 정수인지 판별
    if(sq!=(ll)sq){
        printf("NO\n");
        return 0;
    }
    //두 근을 확인
    long double x=(n+sq)/2.0;
    if(x==(ll)x && x>0){
        printf("YES\n");
    }
    else if(1){
        x=(n-sq)/2.0;
        if(x==(ll)x && x>0){
            printf("YES\n");
        }
    }
    else{
        printf("NO\n");
    }
    return 0;
}
cs

 

 

'백준 문제 풀이' 카테고리의 다른 글

BOJ 1004 어린 왕자  (0) 2021.02.11
BOJ 20187 종이접기  (0) 2021.02.11
BOJ 8452 그래프와 쿼리  (0) 2021.02.11
BOJ 9305 Yahtzee  (0) 2021.02.11
BOJ 1463 1로 만들기  (0) 2021.02.11