#1. 문제
#2. 풀이
1. 퀵 정렬
[정의] : 퀵 정렬 알고리즘은 분할-정복 기반의 정렬 알고리즘으로, 피벗 원소를 기준으로 왼쪽은 피벗 원소보다 작은 원소들, 오른쪽은 큰 원소들로 정렬하고, 피벗 원소를 기준으로 두 부분 배열로 분할하여 재귀적으로 정렬 작업을 수행합니다. 퀵 정렬 알고리즘의 평균 시간 복잡도는 O(n log n)이지만, 최악의 경우 O(n²)입니다. 이때, 최악의 경우를 방지하기 위해, 퀵 정렬 알고리즘 수행 과정에서 피벗 원소의 선택을 "중간 값"으로 선택하는 Median-of-three 방법을 사용할 수 있습니다.
2. 30의 배수는 자릿수의 합이 3으로 나누어 떨어지며, 마지막 자릿수는 0이다!
- 입력받은 숫자를 문자열 형식의 변수에 저장하고, 사전 역순으로 퀵 정렬을 수행합니다.
- 각 자릿수를 더해, 3으로 나누어 떨어지는지 확인하는 동시에, 마지막 자릿수가 0인지 확인합니다.
#3. 코드
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
string N;
int FindMedian(string& str, int l, int r)
{
int m = l + (r-l)/2;
if(str[l] > str[m])
{
swap(str[l], str[m]);
}
if(str[l] > str[r])
{
swap(str[l], str[r]);
}
if(str[m] > str[r])
{
swap(str[m], str[r]);
}
return m;
}
int Partition(string& str, int l, int r)
{
int pivIdx = FindMedian(str, l, r);
swap(str[pivIdx], str[r]);
int piv = str[r];
int i = l-1;
for(int j=l; j<r; ++j)
{
if(str[j] >= piv)
{
i++;
swap(str[j], str[i]);
}
}
swap(str[i+1], str[r]);
return i+1;
}
void QuickSort(string& str, int l, int r)
{
if(l < r)
{
int piv = Partition(str, l, r);
QuickSort(str, l, piv-1);
QuickSort(str, piv+1, r);
}
}
void FindMaxMultipleOf30(string& str)
{
bool hasZero = false;
int sum = 0;
for(const auto& c : str)
{
sum += c-'0';
if(c == '0') hasZero = true;
}
if(hasZero && sum%3 == 0)
{
cout << str;
}
else{
cout << -1;
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> N;
// #1. 퀵 정렬
QuickSort(N, 0, N.length()-1);
// #2. 30의 배수중 최대가 되는 수
FindMaxMultipleOf30(N);
return 0;
}
'문제 풀이 > BOJ 문제 풀이' 카테고리의 다른 글
[BOJ알고리즘, C++]#10825_국영수, 정렬, 병합 정렬 (1) | 2024.02.05 |
---|---|
[BOJ알고리즘, C++]#11656_접미사 배열, 정렬, 퀵 정렬, 병합 정렬 (0) | 2024.02.05 |
[BOJ알고리즘, C++]#11399_ATM, 정렬, 병합 정렬, 퀵 정렬 (1) | 2024.01.26 |
[BOJ알고리즘, C++]#2217_로프, 정렬 알고리즘, 병합 정렬 (0) | 2024.01.26 |
[BOJ알고리즘, C++]#1956_운동, 최단 경로, 플로이드, 플로이드 워셜 (1) | 2024.01.26 |