https://www.acmicpc.net/problem/15649

#include <iostream>
#include <vector>
using namespace std;
int N, M;
void bruteForce(vector<int> selected, int left_num); // selected: 현재 고른 순열, left_num: 더 골라야하는 개수
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> N >> M;
vector<int> v;
bruteForce(v, M);
return 0;
}
void bruteForce(vector<int> selected, int left_num){
//기저사례
if(left_num == 0){
for(auto& element : selected){
cout << element << ' ';
}
cout << '\n';
}
for(int i = 1; i <= N; i++){
bool exist = false;
for(auto itr = selected.begin(); itr != selected.end(); ++itr){
if(*itr == i){
exist = true;
break;
}
}
if(exist == false){
selected.push_back(i);
bruteForce(selected, left_num - 1);
selected.pop_back();
}
}
}
#include <iostream>
#include <vector>
using namespace std;
int N, M;
vector<bool> visited; // 1부터 N까지 사용 여부를 저장 (인덱스 1부터 사용)
void bruteForce(vector<int>& permutation, int depth) {
if (depth == M) { // 기저사례: M개가 골라진 경우
for (int num : permutation) {
cout << num << ' ';
}
cout << '\n';
return;
}
// 1부터 N까지 순서대로 탐색 (사전순 증가)
for (int i = 1; i <= N; i++) {
if (!visited[i]) { // 사용되지 않은 원소인 경우
visited[i] = true;
permutation.push_back(i);
bruteForce(permutation, depth + 1);
permutation.pop_back(); // 백트래킹: 마지막 원소 제거
visited[i] = false;
}
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> N >> M;
visited.assign(N + 1, false); // N개 숫자를 위해 false로 초기화
vector<int> permutation; // 현재까지 골라진 순열을 저장할 벡터
bruteForce(permutation, 0);
return 0;
}
vector 내부를 순회하며 O(M) 시간으로 중복 여부를 검사visited 배열을 사용하여 O(1) 시간에 중복 여부 확인 가능vector<int>를 값으로 전달(pass-by-value) → 호출마다 복사 비용 발생 pop_back()으로 상태 복원 → 메모리 효율 및 속도 향상selected → permutation 문제 해결 역량
백트래킹 문제의 기본 패턴을 충분히 익히고, visited 배열을 활용한 효율적인 중복 제거 방식 이해
효율성과 가독성 모두 중요
작은 최적화의 힘
불필요한 복사 제거, O(M) → O(1) 개선 등 작은 변화가 전체 성능에 끼치는 영향 체감