27986번: 평범한 구성적 문제
정수 N과 M개의 정수 쌍 (L1,R1),(L2,R2),⋯(LM,RM)이 주어진다. 이제 아래 조건을 만족하면서 값 K를 최대화시키는 수열 X를 찾아야 한다. X는 K 이하의 양의 정수 N개로 구성되어
www.acmicpc.net
문제가 수학적인 표현이 많이 쓰여, 다소 이해하기 어렵다고 생각한다.
문제 설명
문제에서 요구하는 것은 배열 X를 구하는 것이며, 배열 X는 1부터 K이하의 수로 구성되어 있다.
문제의 입력으로 주어지는 것들은 조건이며, 조건들을 만족하면서 K가 최대가 되게 하는 배열 X를 구하는 문제이다.
K의 최대값은 하나지만, 이때 배열 X는 여러 가지 경우가 나올 수 있다.
(편의상 K′을 K의 최대값이라 정의하겠다)
문제 접근
문제에서 주어지는 입력 중에서 Ri−Li+1 (구간의 길이)가 L이라고 하면,
(L안에 들어갈 수 있는 원소의 종류의 최대는 L이므로) K′은 L이하여야 한다.
따라서, 모든 (Li,Ri)에 대해서 Ri−Li+1 값 중에서 최소값이 K′이 된다는 것은 직감적으로 알 수 있을 것이다.
결론적으로, K′을 구한 후에 모든 (Li,Ri)에 대해 조건에 맞게끔 적절히 배열 X를 구성하면 된다.
더 좋은 방법
K′이 정해지면, (Li,Ri)의 값에 상관없이 항상 답을 만족하는 배열 X를 만들 수 있다.
즉, K′이 정해지면, (Li,Ri)의 최악의 경우에도 답을 만족하는 X가 항상 존재한다는 것이다.
예를 들어 N=7, K′=3이라고 하면, 이때 최악의 (Li,Ri) 값은 (1,3), (2,4), (3,5), (4,6), (5,7) 이다.
이때, 1231231 와 같이 배열 X를 구성하면 항상 답이 된다.
(직접 해보면, 조건을 만족한다는 것을 알 수 있을 것이다.)
(항상 조건을 만족하는 배열 X가 존재하는 이유는 문제의 조건이 연속된 구간 단위로 주어지기 때문이라고 생각하면 된다.)
똑같이, K′=5라면 N의 길이에만 맞춰서 1234512345123451234512345... 이런식으로 배열X를 구성하면 된다.
최악의 경우(K′길이의 모든 (Li,Ri)쌍이 있는 경우)에도 위의 방법대로 배열 X를 구성하면 조건을 만족했다.
따라서, 입력에 대해 K′( = Ri−Li+1의 최소값)을 구하고 1234...K′1234...K′.... 와 같이 배열 X를 구성하면 된다.
#include <bits/stdc++.h> | |
using namespace std; | |
int main() | |
{ | |
ios_base::sync_with_stdio(false); cin.tie(NULL); | |
int N, M; cin >> N >> M; | |
int k = INT_MAX; | |
while (M--) { | |
int a, b; cin >> a >> b; | |
k = min(k, b-a+1); | |
} | |
for (int i=1; i<=N; i++) { | |
cout << (i % k == 0 ? k : i % k) << ' '; | |
} | |
return 0; | |
} |

'✏️ 알고리즘 > PS 기록' 카테고리의 다른 글
[CodeForces] #905 (Div.3) A~F 업솔빙 (1) | 2023.10.23 |
---|---|
[2023 하반기 ICT 인턴십] 코딩테스트 후기 (0) | 2023.07.20 |
[백준 10220번] Self Representing Seq (1) | 2023.05.17 |
[백준 13275번] 가장 긴 팰린드롬 부분 문자열 (1) | 2023.05.15 |
[백준 17425번] 약수의 합 (2) | 2023.05.02 |