백준 1463번 https://www.acmicpc.net/problem/1463
문제
정수 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
출력
1
ABB
예제 2
입력
1
2 0
출력
1
BA
예제 3
입력
1
5 8
출력
1
-1
예제 4
입력
1
10 12
출력
1
BAABBABAAB
처음에는 ‘AA…A’부터 ‘BB…B’까지 모든 경우의 수를 비교하는 방법으로 풀어봤는데 당연하게 시간초과가 나왔다. 그래서 생각해본게 A와 B의 각각의 개수를 지정해보는 방법을 생각해봤다.
A의 개수 = 3, B의 개수 = 2라고 할 때, K의 수를 최대로 만들 수 있는 방법은 “AAABB”로 만드는 방법이고, K는 A와 B의 개수를 곱해서 6이 된다.
정리를 하면 다음의 조건을 만들 수 있다.
- N = (A의 개수) + (B의 개수)
- 0 <= k <= (A의 개수) * (B의 개수)
A의 개수와 B의 개수를 구하면 K의 값에 맞게 조합해주면된다. (A의 개수) - 1의 A를 앞에 두고, B를 뒤에 둔 후에, 마지막 A의 위치를 K 값에 따라 위치해주면 된다.
K의 범위는 n*(n-1)/2까지 이기 때문에 K개의 조건을 못맞추는 경우가 존재합니다.
N = 5라고 가정해보면, K는 최대 10까지 입력으로 주어질 수 있습니다. 그렇지만 A와 B로 구성할 수 있는 최대 K의 수는 6이기 때문에 7이상의 수는 -1을 출력해야합니다.
코드 (Python)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
if __name__ == '__main__':
import sys
n, k = map(int, sys.stdin.readline().split())
a, b = 0, n # A의 개수, B의 개수
while (k > a*b and b > 0):
a += 1
b -= 1
if b == 0:
print(-1)
elif a == 0:
print("B"*b)
else:
remain = k - (b * (a-1))
print("A"*(a-1)+"B"*(b-remain)+"A"+"B"*remain)