문제링크 : https://www.acmicpc.net/problem/1083
1083번: 소트
크기가 N인 배열 A가 있다. 배열에 있는 모든 수는 서로 다르다. 이 배열을 소트할 때, 연속된 두 개의 원소만 교환할 수 있다. 그리고, 교환은 많아봐야 S번 할 수 있다. 이때, 소트한 결과가 사전
www.acmicpc.net
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int MAX = 987654321;
int N, S;
int arr[51];
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> N;
for(int i=0; i<N; i++)
{
cin >> arr[i];
}
cin >> S;
for(int i=0; i<N; i++)
{
int max = arr[i];
int maxi = i;
for(int j= i+1; j<min(N, i+S+1); j++) //N or S범위내까지
{
if(max < arr[j]) //범위내 가장 큰 값 및 인덱스 저장
{
max = arr[j];
maxi = j;
}
}
for(int j=maxi; j>i; j--) //가장 큰 값 인덱스 기준으로 swap
{
swap(arr[j], arr[j-1]);
S--; //매 swap 마다 카운트 감소
}
}
for(int i=0; i<N; i++)
{
cout << arr[i] << " ";
}
}
처음에 단순 버블정렬 문제로 이해하고 풀었다가 상당히 고민했던 문제이다.
주어진 S 범위 내에 가장 큰 값을 위로 끌어올리는 것을 반복하는 문제였다.
먼저 처음에 비교 대상으로 삼을 max, maxi(인덱스) 값을 초기화해놓고 그 다음값 ~ S 범위내에 가장 큰 값을 확인하여 max와 maxi를 갱신한다.
해당 내용이 수행되는 반복문에서 min(N, i+S+1)을 해주었는데 j이 이 둘 모두보다 작아야하기 때문에 더 작은 값을 선택하도록 해주었다. (N범위 이내 or 현재 i 기준 S 범위 이내)
이후 갱신했던 maxi를 기준으로 위로 swap을 해주며, 매 swap 마다 교환횟수가 차감되므로 S또한 감소시켜준다.
위를 반복하여 정렬을 마치고 정렬된 배열을 출력해주면 된다.
5
3 5 1 2 4
2
i = 0 / 3 기준
탐색 가능 범위 : 3 5 1
범위내 최대값 : 5
범위내 최대값 인덱스 : 1
정렬후 : 5 3 1 2 4(swap 1회 발생) (S=1)
i = 1 / 3 기준
탐색 가능 범위 : 3 1
범위내 최대값 : 3 (현위치 동일 이후 패스)
정렬후 : 5 3 1 2 4
i = 2 / 1 기준
탐색 가능 범위 : 1 2
범위내 최대값 : 2
범위내 최대값 인덱스 : 3
정렬후 : 5 3 2 1 4 (swap 1회 발생) (S=0)
S=0 이므로 정렬 종료
결과값 : 5 3 2 1 4
'백준 > 골드' 카테고리의 다른 글
[백준 1958번] LCS 3 (C++) (0) | 2023.11.18 |
---|---|
[백준 15486번] 퇴사 2 (C++) (0) | 2023.11.16 |
[백준 12904번] A와 B (C++) (0) | 2023.11.13 |
[백준 5052번] 전화번호 목록 (C++) (0) | 2023.11.11 |
[백준 14226번] 이모티콘 (C++) (0) | 2023.11.09 |