๋ฐฑ ํธ๋ํน(Back Tracking)
ํ์ ์กฐ๊ฑด์ด ์ฃผ์ด์ก์ ๋ ํด๋ฅผ ์ป์ ๋๊น์ง ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ฒ์ฌํ๋ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๊ฐ๋ค๊ฐ ๋ค์ ๋์์์ ๋ค๋ฅธ ๊ธธ๋ก ๊ฐ๋ค.
- ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ๊ณ ๋ คํด์ผ ํ๋ฏ๋ก ์ฌ๊ท ํจ์๋ฅผ ์ด์ฉํ DFS๋ฅผ ์ฌ์ฉํ๋ค.
๊ธฐ๋ณธ ์๋ฆฌ
https://www.acmicpc.net/problem/15649
15649๋ฒ: N๊ณผ M (1)
ํ ์ค์ ํ๋์ฉ ๋ฌธ์ ์ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์์ด์ ์ถ๋ ฅํ๋ค. ์ค๋ณต๋๋ ์์ด์ ์ฌ๋ฌ ๋ฒ ์ถ๋ ฅํ๋ฉด ์๋๋ฉฐ, ๊ฐ ์์ด์ ๊ณต๋ฐฑ์ผ๋ก ๊ตฌ๋ถํด์ ์ถ๋ ฅํด์ผ ํ๋ค. ์์ด์ ์ฌ์ ์์ผ๋ก ์ฆ๊ฐํ๋ ์์๋ก ์ถ๋ ฅํด์ผ ํ๋ค.
www.acmicpc.net
#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
15650๋ฒ: N๊ณผ M (2)
ํ ์ค์ ํ๋์ฉ ๋ฌธ์ ์ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์์ด์ ์ถ๋ ฅํ๋ค. ์ค๋ณต๋๋ ์์ด์ ์ฌ๋ฌ ๋ฒ ์ถ๋ ฅํ๋ฉด ์๋๋ฉฐ, ๊ฐ ์์ด์ ๊ณต๋ฐฑ์ผ๋ก ๊ตฌ๋ถํด์ ์ถ๋ ฅํด์ผ ํ๋ค. ์์ด์ ์ฌ์ ์์ผ๋ก ์ฆ๊ฐํ๋ ์์๋ก ์ถ๋ ฅํด์ผ ํ๋ค.
www.acmicpc.net
#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
15651๋ฒ: N๊ณผ M (3)
ํ ์ค์ ํ๋์ฉ ๋ฌธ์ ์ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์์ด์ ์ถ๋ ฅํ๋ค. ์ค๋ณต๋๋ ์์ด์ ์ฌ๋ฌ ๋ฒ ์ถ๋ ฅํ๋ฉด ์๋๋ฉฐ, ๊ฐ ์์ด์ ๊ณต๋ฐฑ์ผ๋ก ๊ตฌ๋ถํด์ ์ถ๋ ฅํด์ผ ํ๋ค. ์์ด์ ์ฌ์ ์์ผ๋ก ์ฆ๊ฐํ๋ ์์๋ก ์ถ๋ ฅํด์ผ ํ๋ค.
www.acmicpc.net
#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
15652๋ฒ: N๊ณผ M (4)
ํ ์ค์ ํ๋์ฉ ๋ฌธ์ ์ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์์ด์ ์ถ๋ ฅํ๋ค. ์ค๋ณต๋๋ ์์ด์ ์ฌ๋ฌ ๋ฒ ์ถ๋ ฅํ๋ฉด ์๋๋ฉฐ, ๊ฐ ์์ด์ ๊ณต๋ฐฑ์ผ๋ก ๊ตฌ๋ถํด์ ์ถ๋ ฅํด์ผ ํ๋ค. ์์ด์ ์ฌ์ ์์ผ๋ก ์ฆ๊ฐํ๋ ์์๋ก ์ถ๋ ฅํด์ผ ํ๋ค.
www.acmicpc.net
#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
14889๋ฒ: ์คํํธ์ ๋งํฌ
์์ 2์ ๊ฒฝ์ฐ์ (1, 3, 6), (2, 4, 5)๋ก ํ์ ๋๋๋ฉด ๋๊ณ , ์์ 3์ ๊ฒฝ์ฐ์๋ (1, 2, 4, 5), (3, 6, 7, 8)๋ก ํ์ ๋๋๋ฉด ๋๋ค.
www.acmicpc.net
#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
1182๋ฒ: ๋ถ๋ถ์์ด์ ํฉ
์ฒซ์งธ ์ค์ ์ ์์ ๊ฐ์๋ฅผ ๋ํ๋ด๋ N๊ณผ ์ ์ S๊ฐ ์ฃผ์ด์ง๋ค. (1 ≤ N ≤ 20, |S| ≤ 1,000,000) ๋์งธ ์ค์ N๊ฐ์ ์ ์๊ฐ ๋น ์นธ์ ์ฌ์ด์ ๋๊ณ ์ฃผ์ด์ง๋ค. ์ฃผ์ด์ง๋ ์ ์์ ์ ๋๊ฐ์ 100,000์ ๋์ง ์๋๋ค.
www.acmicpc.net
#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
2661๋ฒ: ์ข์์์ด
์ฒซ ๋ฒ์งธ ์ค์ 1, 2, 3์ผ๋ก๋ง ์ด๋ฃจ์ด์ ธ ์๋ ๊ธธ์ด๊ฐ N์ธ ์ข์ ์์ด๋ค ์ค์์ ๊ฐ์ฅ ์์ ์๋ฅผ ๋ํ๋ด๋ ์์ด๋ง ์ถ๋ ฅํ๋ค. ์์ด์ ์ด๋ฃจ๋ 1, 2, 3๋ค ์ฌ์ด์๋ ๋น์นธ์ ๋์ง ์๋๋ค.
www.acmicpc.net
#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
9663๋ฒ: N-Queen
N-Queen ๋ฌธ์ ๋ ํฌ๊ธฐ๊ฐ N × N์ธ ์ฒด์คํ ์์ ํธ N๊ฐ๋ฅผ ์๋ก ๊ณต๊ฒฉํ ์ ์๊ฒ ๋๋ ๋ฌธ์ ์ด๋ค. N์ด ์ฃผ์ด์ก์ ๋, ํธ์ ๋๋ ๋ฐฉ๋ฒ์ ์๋ฅผ ๊ตฌํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํ์์ค.
www.acmicpc.net
#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/
N-Queens - LeetCode
Can you solve this real interview question? N-Queens - The n-queens puzzle is the problem of placing n queens on an n x n chessboard such that no two queens attack each other. Given an integer n, return all distinct solutions to the n-queens puzzle. You ma
leetcode.com
#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
2580๋ฒ: ์ค๋์ฟ
์ค๋์ฟ ๋ 18์ธ๊ธฐ ์ค์์ค ์ํ์๊ฐ ๋ง๋ '๋ผํด ์ฌ๊ฐํ'์ด๋ ํผ์ฆ์์ ์ ๋ํ ๊ฒ์ผ๋ก ํ์ฌ ๋ง์ ์ธ๊ธฐ๋ฅผ ๋๋ฆฌ๊ณ ์๋ค. ์ด ๊ฒ์์ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ๊ฐ๋ก, ์ธ๋ก ๊ฐ๊ฐ 9๊ฐ์ฉ ์ด 81๊ฐ์ ์์ ์นธ์ผ๋ก ์ด๋ฃจ
www.acmicpc.net
#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/
Sudoku Solver - LeetCode
Sudoku Solver - Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy all of the following rules: 1. Each of the digits 1-9 must occur exactly once in each row. 2. Each of the digits 1-9 must occur exactly once
leetcode.com
#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/
Letter Combinations of a Phone Number - LeetCode
Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.
leetcode.com
#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/
Generate Parentheses - LeetCode
Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.
leetcode.com
#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);
}
};