๋ฐฑ ํธ๋ํน(Back Tracking)
ํ์ ์กฐ๊ฑด์ด ์ฃผ์ด์ก์ ๋ ํด๋ฅผ ์ป์ ๋๊น์ง ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ฒ์ฌํ๋ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๊ฐ๋ค๊ฐ ๋ค์ ๋์์์ ๋ค๋ฅธ ๊ธธ๋ก ๊ฐ๋ค.
- ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ๊ณ ๋ คํด์ผ ํ๋ฏ๋ก ์ฌ๊ท ํจ์๋ฅผ ์ด์ฉํ DFS๋ฅผ ์ฌ์ฉํ๋ค.
๊ธฐ๋ณธ ์๋ฆฌ
https://www.acmicpc.net/problem/15649
#include <iostream>
using namespace std;
int n, m;
int number[8];
bool ck[9];
// ์ค๋ณต ์์ด M๊ฐ๋ฅผ ๊ณ ๋ฅธ ์์ด
void DFS(int t)
{
if (t == m) {
for (int i = 0; i < m; i++)
cout << number[i] << ' ';
cout << '\n';
return;
}
for (int i = 1; i <= n; i++) {
if (!ck[i]) {
ck[i] = true;
number[t] = i;
DFS(t + 1);
ck[i] = false;
}
}
}
int main()
{
cin >> n >> m;
DFS(0);
}
https://www.acmicpc.net/problem/15650
#include <iostream>
using namespace std;
int n, m;
int number[8];
// ์ค๋ณต ์์ด M๊ฐ๋ฅผ ๊ณ ๋ฅธ ์ค๋ฆ์ฐจ์ ์์ด
void DFS(int t, int cnt)
{
if (t == m) {
for (int i = 0; i < m; i++)
cout << number[i] << ' ';
cout << '\n';
return;
}
for (int i = cnt; i <= n; i++) {
number[t] = i;
DFS(t + 1, i + 1);
}
}
int main()
{
cin >> n >> m;
DFS(0, 1);
}
https://www.acmicpc.net/problem/15651
#include <iostream>
using namespace std;
int n, m;
int number[8];
// ์ค๋ณต ํ์ฉํ๊ณ M๊ฐ๋ฅผ ๊ณ ๋ฅธ ์์ด
void DFS(int t)
{
if (t == m) {
for (int i = 0; i < m; i++)
cout << number[i] << ' ';
cout << '\n';
return;
}
for (int i = 1; i <= n; i++) {
number[t] = i;
DFS(t + 1);
}
}
int main()
{
cin >> n >> m;
DFS(0);
}
https://www.acmicpc.net/problem/15652
#include <iostream>
using namespace std;
int n, m;
int number[8];
// ์ค๋ณต ํ์ฉํ๊ณ M๊ฐ๋ฅผ ๊ณ ๋ฅธ ๋น๋ด๋ฆผ์ฐจ์ ์์ด
// ๋น๋ด๋ฆผ์ฐจ์ ์์ด: ๊ธธ์ด๊ฐ K์ธ ์์ด A๊ฐ A1 ≤ A2 ≤ ... ≤ AK-1 ≤ AK๋ฅผ ๋ง์กฑํ๋ ์์ด
void DFS(int t, int cnt)
{
if (t == m) {
for (int i = 0; i < m; i++)
cout << number[i] << ' ';
cout << '\n';
return;
}
for (int i = cnt; i <= n; i++) {
number[t] = i;
DFS(t + 1, i);
}
}
int main()
{
cin >> n >> m;
DFS(0, 1);
}
๋ฌธ์
https://www.acmicpc.net/problem/14889
#include <iostream>
using namespace std;
int answer = 1e9;
int N, arr[20][20], start[10];
void dfs(int index, int count)
{
if (index == N / 2) {
int link[10]{};
for (int i = 0, index1 = 0, index2 = 0; i < N; ++i)
start[index1] == i ? index1++ : link[index2++] = i;
int t1 = 0, t2 = 0;
for (int i = 0; i < N / 2; ++i)
for (int j = i + 1; j < N / 2; ++j) {
t1 += arr[start[i]][start[j]] + arr[start[j]][start[i]];
t2 += arr[link[i]][link[j]] + arr[link[j]][link[i]];
}
if (abs(t1 - t2) < answer)
answer = abs(t1 - t2);
return;
}
for (int i = count; i < N; ++i) {
start[index] = i;
dfs(index + 1, i + 1);
}
}
int main()
{
cin >> N;
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
cin >> arr[i][j];
dfs(0, 0);
cout << answer;
}
https://www.acmicpc.net/problem/1182
#include <iostream>
#include <algorithm>
using namespace std;
int answer, N, S;
int num[20], subsequence[20];
void dfs(int index, int count, int subsequenceCount)
{
if (index == subsequenceCount) {
int sum = 0;
for (int i = 0; i < subsequenceCount; i++)
sum += subsequence[i];
if (sum == S)
answer++;
return;
}
for (int i = count; i < N; i++) {
subsequence[index] = num[i];
dfs(index + 1, i + 1, subsequenceCount);
}
}
int main()
{
cin >> N >> S;
for (int i = 0; i < N; ++i)
cin >> num[i];
for (int i = 1; i <= N; ++i)
dfs(0, 0, i);
cout << answer;
}
https://www.acmicpc.net/problem/2661
#include <iostream>
#include <string>
using namespace std;
int N;
void dfs(int index, string s)
{
if (index == N) {
cout << s;
exit(0);
}
for (int i = 1; i <= 3; ++i) {
string tmp = s + to_string(i);
bool good = true;
for (int j = 1, k = tmp.size() - 1; j <= tmp.size() / 2; ++j, --k)
if (tmp.substr(k, j) == tmp.substr(k - j, j)) {
good = false;
break;
}
if (good)
dfs(index + 1, tmp);
}
}
int main()
{
cin >> N;
dfs(0, "");
}
https://www.acmicpc.net/problem/9663
#include <iostream>
using namespace std;
int n, answer;
bool row[15], right_diagonal[30], left_diagonal[30];
// NxN ์ฒด์คํ ์์ ํธ N๊ฐ๋ฅผ ์๋ก ๊ณต๊ฒฉํ ์ ์๊ฒ ๋๋ ๋ฐฉ๋ฒ์ ์
// ๋ค๋ฅธ ํธ์ด ๊ฐ๋ก, ์ธ๋ก, ๋๊ฐ์ ์ ์์ผ๋ฉด ์๋๋ค.
void dfs(int cnt)
{
if (cnt == n) {
answer++;
return;
}
for (int i = 0; i < n; i++) {
if (row[i] || right_diagonal[i + cnt] || left_diagonal[n - 1 - i + cnt])
continue;
row[i] = right_diagonal[i + cnt] = left_diagonal[n - 1 - i + cnt] = true;
dfs(cnt + 1);
row[i] = right_diagonal[i + cnt] = left_diagonal[n - 1 - i + cnt] = false;
}
}
int main()
{
cin >> n;
dfs(0);
cout << answer;
}
https://leetcode.com/problems/n-queens/description/
#include <vector>
#include <string>
#include <math.h>
using namespace std;
class Solution {
public:
vector<vector<string>> answer;
int check[9];
bool IsValid(int row)
{
for (int i = 0; i < row; i++)
if (check[row] == check[i] || abs(check[row] - check[i]) == abs(row - i))
return false;
return true;
}
void DFS(int n, int row)
{
if (n == row) {
vector<string> temp;
for (int i = 0; i < n; ++i) {
string s = "";
for (int j = 0; j < n; ++j)
s += (check[i] == j ? "Q" : ".");
temp.push_back(s);
}
answer.push_back(temp);
return;
}
for (int i = 0; i < n; ++i) {
check[row] = i;
if (IsValid(row))
DFS(n, row + 1);
}
}
vector<vector<string>> solveNQueens(int n) {
DFS(n, 0);
return answer;
}
};
https://www.acmicpc.net/problem/2580
#include <iostream>
#include <vector>
using namespace std;
int board[9][9];
vector<pair<int, int>> emptyPoint;
void dfs(int index)
{
if (index == emptyPoint.size()) {
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j)
cout << board[i][j] << ' ';
cout << '\n';
}
exit(0);
}
for (int i = 1; i <= 9; ++i) {
pair<int, int> point = emptyPoint[index];
bool flag = true;
int dir[9][2]{ {0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2} };
for (int j = 0; j < 9; ++j) {
if (board[point.first][j] == i || board[j][point.second] == i ||
board[point.first / 3 * 3 + dir[j][0]][point.second / 3 * 3 + dir[j][1]] == i) {
flag = false;
break;
}
}
if (flag) {
board[point.first][point.second] = i;
dfs(index + 1);
board[point.first][point.second] = 0;
}
}
}
int main()
{
for (int i = 0; i < 9; ++i)
for (int j = 0; j < 9; ++j) {
cin >> board[i][j];
if (board[i][j] == 0)
emptyPoint.push_back({ i ,j });
}
dfs(0);
}
https://leetcode.com/problems/sudoku-solver/
#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;
class Solution {
public:
vector<unordered_set<int>> rows;
vector<unordered_set<int>> cols;
vector<unordered_set<int>> boxes;
void solveSudoku(vector<vector<char>>& board)
{
rows.resize(9);
cols.resize(9);
boxes.resize(9);
for (int i = 0; i < 9; ++i)
for (int j = 0; j < 9; ++j)
if (board[i][j] != '.')
insert(i, j, board[i][j] - '0');
fill(board, 0, 0);
}
bool fill(vector<vector<char>>& board, int i, int j)
{
if (i == 8 && j == 9)
return true;
if (j == 9) {
i++;
j = 0;
}
if (board[i][j] == '.') {
for (int value = 1; value < 10; value++) {
if (isValid(i, j, value)) {
board[i][j] = value + '0';
if (fill(board, i, j + 1))
return true;
board[i][j] = '.';
erase(i, j, value);
}
}
return false;
}
return fill(board, i, j + 1);
}
bool isValid(int i, int j, int value)
{
if (rows[i].find(value) == rows[i].end() &&
cols[j].find(value) == cols[j].end() &&
boxes[(i / 3) * 3 + (j / 3)].find(value) == boxes[(i / 3) * 3 + (j / 3)].end())
{
insert(i, j, value);
return true;
}
return false;
}
void insert(int i, int j, int value)
{
rows[i].insert(value);
cols[j].insert(value);
boxes[(i / 3) * 3 + (j / 3)].insert(value);
}
void erase(int i, int j, int value)
{
rows[i].erase(value);
cols[j].erase(value);
boxes[(i / 3) * 3 + (j / 3)].erase(value);
}
};
https://leetcode.com/problems/letter-combinations-of-a-phone-number/submissions/
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Solution {
public:
vector<string> answer;
string digitsToLetters[10] = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
void makeLetters(string digits, string letters, int digitIndex) {
if (digits.size() == digitIndex) {
answer.push_back(letters);
return;
}
int num = digits[digitIndex] - '0';
for (int i = 0; i < digitsToLetters[num].size(); ++i)
makeLetters(digits, letters + digitsToLetters[num][i], digitIndex + 1);
}
vector<string> letterCombinations(string digits) {
if (digits != "") {
makeLetters(digits, "", 0);
sort(answer.begin(), answer.end());
}
return answer;
}
};
https://leetcode.com/problems/generate-parentheses/
#include <vector>
#include <string>
using namespace std;
class Solution {
public:
vector<string> answer;
vector<string> generateParenthesis(int n) {
parenthesisCombinations("", 0, 0, n);
return answer;
}
void parenthesisCombinations(string s, int left, int right, int n) {
if (s.length() == n * 2) {
answer.push_back(s);
return;
}
if (left < n)
parenthesisCombinations(s + "(", left + 1, right, n);
if (left > right)
parenthesisCombinations(s + ")", left, right + 1, n);
}
};