[백준 10974] 모든 순열 (C#, C++) - soo:bak
작성일 :
문제 링크
설명
1
부터 N
까지의 수로 만들 수 있는 모든 순열을 사전순으로 출력하는 문제입니다.
순열이란 N
개의 원소를 서로 다른 순서로 나열한 경우의 집합이며,
이 문제에서는 가능한 모든 순열을 작은 수부터 시작하여 사전순으로 정렬된 형태로 출력해야 합니다.
접근법
1
부터N
까지의 수 중 아직 사용하지 않은 수를 하나씩 선택하며,
현재까지 선택된 순열 뒤에 이어붙이는 방식으로 탐색을 진행합니다.- 선택된 수는 중복되지 않도록 방문 여부를 확인하며 선택하고,
모든 선택이 완료되어 수열의 길이가N
이 되면 해당 순열을 출력합니다. - 이러한 방식은 전형적인 백트래킹(재귀) 구조로 구현할 수 있으며,
사전순 출력을 위해 항상 작은 수부터 탐색합니다.
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
29
30
31
using System;
using System.Collections.Generic;
class Program {
static int n;
static List<int> perm = new List<int>();
static bool[] used;
static void BackTrack() {
if (perm.Count == n) {
Console.WriteLine(string.Join(" ", perm));
return;
}
for (int i = 1; i <= n; i++) {
if (!used[i]) {
used[i] = true;
perm.Add(i);
BackTrack();
perm.RemoveAt(perm.Count - 1);
used[i] = false;
}
}
}
static void Main() {
n = int.Parse(Console.ReadLine());
used = new bool[n + 1];
BackTrack();
}
}
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
#include <bits/stdc++.h>
using namespace std;
typedef vector<int> vi;
int n;
vi p;
vector<bool> used;
void backTrack() {
if (p.size() == (size_t)n) {
for (int i = 0; i < n; i++)
cout << p[i] << (i < n - 1 ? " " : "\n");
} else {
for (int i = 1; i <= n; i++) {
if (!used[i]) {
used[i] = true;
p.push_back(i);
backTrack();
used[i] = false;
p.pop_back();
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
used.resize(n + 1);
backTrack();
return 0;
}