[백준 2697] 다음수 구하기 (C#, C++) - soo:bak
작성일 :
문제 링크
설명
주어진 수와 자리수 구성은 같지만, 그 수보다 큰 수 중 가장 작은 수를 찾는 문제입니다.
- 입력으로 주어지는 수는 최대
80자리
의 자연수이며, - 각 테스트 케이스마다 해당 수의 다음 순열을 찾아야 합니다.
- 만약 사전순으로 다음에 올 수가 없다면
"BIGGEST"
를 출력합니다.
다음 순열(Next Permutation) 알고리듬을 구현하거나 사용하는 전형적인 문제입니다.
접근법
입력 수는 문자열 형태로 주어지며, 각 자릿수를 하나의 문자로 처리할 수 있습니다.
문제의 핵심은 주어진 수보다 큰 수 중 가장 작은 수를 찾는 것이므로,
다음과 같은 다음 순열
구하기 절차를 그대로 따릅니다:
- 뒤에서부터 오름차순이 깨지는 지점을 찾습니다.
- 그 자리보다 큰 수 중 가장 오른쪽에 있는 수를 찾아 위치를 바꿉니다.
- 바꾼 이후의 자릿수들은 오름차순으로 정렬하여 최소값을 구성합니다.
만약 위 절차에서 오름차순이 깨지는 지점을 찾을 수 없다면,
이미 가장 큰 수이므로 "BIGGEST"
를 출력합니다.
Code
C#
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
using System;
using System.Linq;
class Program {
static bool NextPermutation(char[] arr) {
int i = arr.Length - 2;
while (i >= 0 && arr[i] >= arr[i + 1])
i--;
if (i < 0) return false;
int j = arr.Length - 1;
while (arr[j] <= arr[i])
j--;
(arr[i], arr[j]) = (arr[j], arr[i]);
Array.Reverse(arr, i + 1, arr.Length - i - 1);
return true;
}
static void Main() {
int t = int.Parse(Console.ReadLine());
while (t-- > 0) {
var input = Console.ReadLine().ToCharArray();
if (NextPermutation(input)) Console.WriteLine(new string(input));
else Console.WriteLine("BIGGEST");
}
}
}
C++
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
34
35
36
37
38
#include <bits/stdc++.h>
using namespace std;
typedef vector<char> vc;
bool nextPermu(vc& p) {
int n = p.size(), i = n - 2;
while (i >= 0 && p[i] >= p[i + 1])
--i;
if (i < 0) return false;
int j = n - 1;
while (p[j] <= p[i])
--j;
swap(p[i], p[j]);
reverse(p.begin() + i + 1, p.end());
return true;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t; cin >> t;
while (t--) {
string s; cin >> s;
vc p(s.begin(), s.end());
if (nextPermu(p)) {
for (char c : p)
cout << c;
}
else cout << "BIGGEST";
cout << "\n";
}
return 0;
}