[코딩 테스트] Backtracking > N과 M (9)

Cassis_Soda·2025년 3월 25일

코딩 테스트

목록 보기
13/13
post-thumbnail

0. 링크

     백준 문제 링크

1. 설명

N개의 자연수와 자연수 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.

  • N개의 자연수 중에서 M개를 고른 수열
  • 입력

    • 첫째 줄에 자연수 N과 M이 주어진다. (1 ≤ M ≤ N ≤ 8)
    • 둘째 줄에 N개의 수가 주어진다. 입력으로 주어지는 수는 10,000보다 작거나 같은 자연수이다.
  • 출력

    • 한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.
    • 수열은 사전 순으로 증가하는 순서로 출력해야 한다.

입출력 예시

inputoutput
3 1
4 4 2
2
4
4 2
9 7 9 1
1 7
1 9
7 1
7 9
9 1
9 7
9 9

2. 해설

  1. M개의 수를 갖는 순열을 만들기 위한 벡터 printList 선언
  2. 입력을 받아 처리할 수를 저장하는 벡터 inputList 선언
  3. 이전의 입력값이 중복인지 아닌지 검출하는 prev 선언
    • 중복값이 연속으로 등장하므로 (정렬하고 시작) 이전값을 검사
  4. Backtracking()함수 내에서 아래와 같이 반복한다.

    1) list.size() == m 이면 return후 출력
    2) i = 1; i <= N인 동안 다음을 반복한다.

    if (!visited[i] && prev != inputList[i])
    (1) visited[i] = true
    (2) list.push_back()
    (3) Backtracking(inputList[i])
    (4) list.pop_back()
    (5) visited[i] = false
    (6) prev = inputList[i] // 이 레벨에서 사용된 값 기록

3. 코드

#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>

using namespace std;

int n, m;
int k;
vector <int> inputList;
vector <int> printList;
vector <bool> visited;


void print()
{
	for (size_t i = 0; i < printList.size(); i++)
		cout << printList[i]  << " ";
	cout << '\n';

}

void Backtracking(int key)
{
	if (printList.size() == m)
	{
		print();
		return;
	}
	int prev = -1;
	for (size_t i = 0; i < inputList.size(); i++)
	{
		if (!visited[i] && inputList[i] != prev)
		{
			visited[i] = true;
			printList.push_back(inputList[i]);
			Backtracking(inputList[i]);
			printList.pop_back();
			visited[i] = false;
			prev = inputList[i]; 
			
		}
	}
}

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

	for (int i = 0; i < n; i++)
	{
		int num;
		cin >> num;
		inputList.push_back(num);
	}
	sort(inputList.begin(), inputList.end());
	visited = vector <bool>(n, false);
	
	Backtracking(-1);
}

4. 감상

     백트래킹을 이해했다고 생각한 날 부숴버린 문제. 이해하고 있는게 아니라 외우고 있던 거였다. 이렇게 저렇게 문제를 풀어보며 IDE상에서는 문제없이 풀었지만 백준에 제출하니 시간초과를 뱉어내더라. 결국 AI의 해설의 도움을 받아서 해결했다. 다시 풀어봐야한다.

0개의 댓글