문제
정수 N과 K가 주어졌을 때, 다음 두 조건을 만족하는 문자열 S를 찾는 프로그램을 작성하시오.
- 문자열 S의 길이는 N이고, 'A', 'B'로 이루어져 있다.
- 문자열 S에는 0 ≤ i < j < N 이면서 s[i] == 'A' && s[j] == 'B'를 만족하는 (i, j) 쌍이 K개가 있다.
입력
첫째 줄에 N과 K가 주어진다. (2 ≤ N ≤ 50, 0 ≤ K ≤ N(N-1)/2)
출력
첫째 줄에 문제의 조건을 만족하는 문자열 S를 출력한다. 가능한 S가 여러 가지라면, 아무거나 출력한다. 만약, 그러한 S가 존재하지 않는 경우에는 -1을 출력한다.
예제 입력 1 | 예제 출력 1 |
3 2 | ABB |
예제 입력 2 | 예제 출력 2 |
2 0 | BA |
예제 입력 3 | 예제 출력 3 |
5 8 | -1 |
예제 입력 4 | 예제 출력 4 |
10 12 | BAABBABAAB |
CODE
#include <bits/stdc++.h> using namespace std; void solve(int N, int K) { if(K > (N / 2) * (N / 2 + N % 2)) // 문자열을 만들 수 없는 경우 { cout << -1; } else if(K == 0) // B*A* 의 상태로 출력 { for(int i = 0; i < N - 1; i++) cout << 'B'; cout << 'A'; } else // B를 N개 만든 뒤, 앞에서부터 차례로 A가 들어갈 수 있는 경우 A로 바꿈 { for(int i = 0, j = 1, sum = 0; i < N; i++) { if(N - j - i > 0 && sum + N - j - i <= K) { cout << 'A'; sum += N - j++ - i; } else cout << 'B'; } } } int main() { ios::sync_with_stdio(false); cin.tie(NULL); int N, K; cin >> N >> K; solve(N, K); }
COMMENT
1. 문자열을 만들 수 없는 경우
- A를 a개, B를 b개 사용하여 문자열을 만든다고 가정하자. K는 문자열이 A*B* 꼴일 때 최댓값을 가지며 값은 ab이다.
- 이 때, a+b=N 이므로 ab의 최댓값은 a(N-a)의 최댓값과 같으며, a=N/2일 때 최댓값을 가진다.
- 따라서 a=N/2, b=N/2일 때의 값보다 입력받은 K값이 크면 문자열을 만들 수 없다.
2. K의 값이 0인 경우
- B*A* 꼴의 문자열일 경우 K의 값은 0이 된다.
3. 문자열을 만들 수 있는 경우
1에서 K의 값이 0이상 ab이하인 모든 문자열을 만들 수 있다는 것을 증명했으므로, B가 N개인 문자열을 만들어 놓고 앞에서부터 A로 바꾸어보며 K와 비교해보면 된다.
- i를 문자열의 index, j를 이제까지 사용한 A의 개수 + 1, K까지 도달하고자 하는 값을 sum이라고 하자.
- 차례로 A를 넣는다면 sum의 값은 N-i-j가 증가할 것이므로, sum+N-i-j의 값이 K이하일 경우 계속해서 A를 넣어주자.
도움이 되셨다면 공감 꾸욱! 부탁드립니다 ~~!!😊
'Algorithm > Greedy' 카테고리의 다른 글
[BOJ] 2138 : 전구와 스위치 C++ (0) | 2021.02.20 |
---|---|
[BOJ] 1080 : 행렬 C++ (0) | 2021.02.18 |
[프로그래머스] 구명보트 C++ (0) | 2021.02.15 |
[프로그래머스] 조이스틱 C++ (0) | 2021.02.14 |
댓글