본문 바로가기

문과 코린이의, [C. C++] 기록/C++ 백준 문제풀이

[문과 코린이의 IT 기록장] C++ 백준 문제풀이[BF] - 다음 순열 (10972)

반응형

[문과 코린이의 IT 기록장] C++ 백준 문제풀이[BF] - 다음 순열 (10972)

[문과 코린이의 IT 기록장] C++ 백준 문제풀이[BF] - 다음 순열 (10972)

 


 

 

10972번: 다음 순열

첫째 줄에 입력으로 주어진 순열의 다음에 오는 순열을 출력한다. 만약, 사전순으로 마지막에 오는 순열인 경우에는 -1을 출력한다.

www.acmicpc.net

[ 문제 ]

1부터 N까지의 수로 이루어진 순열이 있다. 이때, 사전순으로 다음에 오는 순열을 구하는 프로그램을 작성하시오.

사전 순으로 가장 앞서는 순열은 오름차순으로 이루어진 순열이고, 가장 마지막에 오는 순열은 내림차순으로 이루어진 순열이다.

N = 3인 경우에 사전순으로 순열을 나열하면 다음과 같다.

  • 1, 2, 3
  • 1, 3, 2
  • 2, 1, 3
  • 2, 3, 1
  • 3, 1, 2
  • 3, 2, 1

[ 입력 ]

  • 첫째 줄에 N(1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄에 순열이 주어진다.

[ 출력 ]

  • 첫째 줄에 입력으로 주어진 순열의 다음에 오는 순열을 출력한다. 만약, 사전순으로 마지막에 오는 순열인 경우에는 -1을 출력한다.

[ 코드1 ]

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

bool next_permutation(vector <int>& a, int n) {
	// 계산이 가능한 순열부분인가?
	int i = n - 1;
	while (i > 0 && a[i - 1] >= a[i]) // 마지막순열이 아니고, a[i-1]>=a[i]인 부분 찾기
	{
		i -= 1;
	}
	if (i <= 0) // 마지막순열
	{
		return false;
	}

	// 계산
	int j = n - 1; // 수열의 가장 마지막 값
	while (a[j] <= a[i - 1]) 
		// 이 조건에 해당하지 않으면, a[j]>a[i-1]인 것.
		// 뒷 부분부터 검사. 
	{
		j -= 1;
	}
	swap(a[i - 1], a[j]);

	j = n - 1; // 수열의 가장 마지막 값
	while (i<j)
	{
		swap(a[i], a[j]);
		i += 1;
		j -= 1;
	}
	return true;
}

int main() {
	int N;
	cin >> N;

	vector <int> a(N);
	for (int i = 0; i < N; i++)
	{
		cin >> a[i];
	}

	if (next_permutation(a,N))
	{
		for (int i = 0; i < N; i++)
		{
			cout << a[i] << ' ';
		}
	}
	else // 마지막 순열일 경우
	{
		cout << "-1";
	}
	cout << '\n';

	return 0;
}

[ 코드2 ]

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

int main() {
	int n;
	cin >> n;

	vector <int> a(n);
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
	}

	if (next_permutation(a.begin(),a.end())) // 다음 순열 찾는 알고리즘
	{
		for (int i = 0; i < n; i++)
		{
			cout << a[i] << '\n';
		}
	}
	else
	{
		cout << "-1";
	}

	cout << '\n';
	return 0;

}
반응형