백트래킹 2

2025. 4. 4. 12:42·알고리즘(코딩테스트)

백트래킹 문제를 풀다가 중복제거, 오름차순 정렬 등을 좀 더 간단하게 하고 싶어서 정리한 내용입니다.

 

기존에 정리한 글

https://gbleem.tistory.com/124

 

백트래킹

1. 백트래킹쉽게 말해서 가능한 모든 경우의 수를 다 해보는 알고리즘이다.재귀 함수를 사용하여, 현재 상태에서 가능한 모든 후보군을 따라 들어가며 탐색하는 알고리즘! 문제를 보고, 주어진

gbleem.tistory.com

 

1. 순열 구하기


기본 형식의 백트래킹 코드를 돌리면 순열을 구할 수 있다. 

  • 1 ~ n까지의 숫자 중에서 m개를 뽑는 경우
  • 중복은 제거
void Choose(int cur)
{
	if (cur == m)
	{
		for (const int& a : ans)
		{
			cout << a << " ";
		}
		cout << "\n";

		return;
	}

	for (int i = 1; i <= n; ++i)
	{
		if (!isused[i])
		{
			ans.push_back(i);
			isused[i] = 1;
			Choose(cur + 1);
			ans.pop_back();
			isused[i] = 0;
		}
	}
}

 

4 2를 input으로 넣었을 때 아래와 같은 결과가 나온다.

 

 

2. 조합 구하기


순열을 구하는 코드에서 시작점을 뜻하는 start라는 매개변수를 추가하여 보면 아래와 같이 구현할 수 있다.

void Choose(int cur, int start)
{
	if (cur == m)
	{
		for (const int& a : ans)
		{
			cout << a << " ";
		}
		cout << "\n";

		return;
	}

	for (int i = start; i <= n; ++i)
	{
        ans.push_back(i);
        Choose(cur + 1, i + 1);
        ans.pop_back();
	}
}

 

이 코드의 실행 결과는 아래와 같다.

 

 

3. 실습


조합을 구하기

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

더보기
#include <iostream>
#include <vector>
using namespace std;

int n, m;
int isused[10];
vector<int> ans;

void Choose(int cur, int start)
{
	if (cur == m)
	{
		for (const int& a : ans)
		{
			cout << a << " ";
		}
		cout << "\n";

		return;
	}

	for (int i = start; i <= n; ++i)
	{
        ans.push_back(i);
        Choose(cur + 1, i + 1);
        ans.pop_back();
	}
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> n >> m;

	Choose(0, 1);
}

 

오름차순 조합 구하기

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

더보기
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int n, m;
int board[10];
vector<int> ans;

void Choose(int cur, int start)
{
	if (cur == m)
	{
		for (const int& a : ans)
			cout << a << " ";
		cout << "\n";
		return;
	}

	//index
	for (int i = start; i < n; ++i)
	{
		ans.push_back(board[i]);
		Choose(cur + 1, i + 1);
		ans.pop_back();
	}
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> n >> m;

	for (int i = 0; i < n; ++i)
	{
		cin >> board[i];
	}
	sort(board, board + n);
	Choose(0,0);

}

 

중복이 가능한 오름차순 조합

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

  • 내 처음 풀이
더보기
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;

int n, m;
int board[10];
vector<int> ans;
set<vector<int>> s;

void Choose(int cur)
{
	if (cur == m)
	{		
		s.insert(ans);
		return;
	}
	for (int i = 0; i < n; ++i)
	{
		if (ans.empty() || (!ans.empty() && ans.back() <= board[i]))
		{
			ans.push_back(board[i]);
			Choose(cur + 1);
			ans.pop_back();
		}
	}
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> n >> m;
	for (int i = 0; i < n; ++i)
		cin >> board[i];

	sort(board, board + n);

	Choose(0);
	for (const auto si : s)
	{
		for (const auto a : si)
			cout << a << " ";
		cout << "\n";
	}
}
  • 다른 아이디어
    • 생각해볼만 하지만, 잘 이해는 안된다.
    • 중복은 그냥 set으로 처리하는게 나을지도
더보기
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int n, m;
int board[10];
int ans[10];

void Choose(int cur, int start)
{
	if (cur == m)
	{
		for (int i = 0; i < m; ++i)
			cout << ans[i] << " ";
		cout << "\n";
		return;
	}
	int temp = -1;
	for (int i = start; i < n; ++i)
	{
		if (board[i] != temp)
		{		
			ans[cur] = board[i];
			temp = ans[cur];
			Choose(cur + 1, i);
		}
	}
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> n >> m;
	for (int i = 0; i < n; ++i)
		cin >> board[i];

	sort(board, board + n);

	Choose(0, 0);
}

'알고리즘(코딩테스트)' 카테고리의 다른 글

LCS  (0) 2025.04.23
DP (배낭 문제)  (0) 2025.04.11
최단 경로 구하기 (다익스트라, 벨만-포드)  (0) 2025.03.25
정렬 및 탐색 알고리즘 정리  (0) 2025.03.21
백트래킹  (0) 2025.03.14
'알고리즘(코딩테스트)' 카테고리의 다른 글
  • LCS
  • DP (배낭 문제)
  • 최단 경로 구하기 (다익스트라, 벨만-포드)
  • 정렬 및 탐색 알고리즘 정리
gbleem
gbleem
gbleem 님의 블로그 입니다.
  • gbleem
    gbleem 님의 블로그
    gbleem
  • 전체
    오늘
    어제
    • 분류 전체보기 (184)
      • Unreal Engine (73)
      • C++ (19)
      • 알고리즘(코딩테스트) (27)
      • TIL (60)
      • CS (4)
      • 툴 (1)
  • 블로그 메뉴

    • 홈
    • 카테고리
  • 링크

    • 과제용 깃허브
    • 깃허브
    • velog
  • 공지사항

  • 인기 글

  • 태그

    C++
    blend pose
    actor 클래스
    템플릿
    DP
    enhanced input system
    싱글턴
    motion matching
    const
    Vector
    addonscreendebugmessage
    map을 vector로 복사
    cin함수
    BFS
    매크로 지정자
    applydamage
    상속
    additive animation
    character animation
    gamestate
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
gbleem
백트래킹 2
상단으로

티스토리툴바