深度优先遍历的基本框架
其中:
a是当前获得的部分解;
k是搜索深度;
input是其它输入;
is_a_solution(a,k,input)判断当前的部分解向量a[1...k]是否是一个符合条件的解;
construct_candidates(a,k,input,c,ncandidates)根据目前状态,构造这一步可能的选择,存入c[]数组,其长度存入ncandidates;
process_solution(a,k,input)对于符合条件的解进行处理,通常是输出、计数等;
make_move(a,k,input)和unmake_move(a,k,input)前者将采取的选择更新到原始数据结构上,后者把这一行为撤销。
填充封闭区域
#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>
using namespace std;
//构造记录坐标的结构体
struct Point
{
int x;
int y;
Point(int _x, int _y) :x(_x), y(_y){};
bool operator==(const Point&point)
{
if (x == point.x && y == point.y)
{
return true;
}
return false;
}
};
//递归函数
void backtrack(vector<vector<char>>&board, int row, int column, Point point, vector<vector<int>>&visit, vector<Point>&output)
{
//输入有效性判断
if (point.x < 0 || point.x >= row || point.y < 0 || point.y >= column)
{
visit[point.x][point.y] = 1;
return;
}
//递归基
if (board[point.x][point.y] == 'X')
{
visit[point.x][point.y] = 1;
return;
}
output.push_back(point);
visit[point.x][point.y] = 1;
//往右深入
Point point1(point.x, point.y + 1);
if (point1.y<column)
{
if (visit[point1.x][point1.y] == 0)
{
backtrack(board, row, column, point1, visit, output);
}
}
//往下深入
Point point2(point.x + 1, point.y);
if (point2.x<row)
{
if (visit[point2.x][point2.y] == 0)
{
backtrack(board, row, column, point2, visit, output);
}
}
//往左深入
Point point3(point.x, point.y - 1);
if (point3.y>=0)
{
if (visit[point3.x][point3.y] == 0)
{
backtrack(board, row, column, point3, visit, output);
}
}
//往上深入
Point point4(point.x - 1, point.y);
if (point4.x>=0)
{
if (visit[point4.x][point4.y] == 0)
{
backtrack(board, row, column, point4, visit, output);
}
}
}
void FlipOSurrendedByX(vector<vector<char>>&board, int row, int column)
{
//创建并初始化记录每个位置是否被访问到的数据结构
vector<vector<int>>visit;
for (int i = 0; i < board.size(); ++i)
{
vector<int>vec1;
for (int j = 0; j < board[i].size(); ++j)
{
vec1.push_back(0);
}
visit.push_back(vec1);
}
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < column; ++j)
{
vector<Point>discovered;
Point point(i, j);
if (visit[i][j] != 1)
{
backtrack(board, row, column, point, visit, discovered);
}
if (!discovered.empty())
{
for (auto point : discovered)
{
if (point.x == 0 || point.x == row - 1 || point.y == 0 || point.y == column - 1)
{
discovered.clear();
break;
}
}
for (auto point : discovered)
{
board[point.x][point.y] = 'X';
}
}
}
}
return;
}
int main()
{
vector<vector<char>>input;
const int size = 5;
for (int i = 0; i < size;++i)
{
vector<char>vec1;
for (int j = 0; j < size;++j)
{
char ch;
cin >> ch;
vec1.push_back(ch);
}
input.push_back(vec1);
}
FlipOSurrendedByX(input, size, size);
for (auto& row:input)
{
for (auto& column:row)
{
cout << column;
}
cout << endl;
}
system("pause");
return 0;
}
测试结果如下:
生成N个数字的全排列
(1)判断当前解是否为有效解:当前解的大小和输入序列的大小相同;
(2)是则输出;
(3)不是的话,则根据当前的状态,构造下一个可能的取值;
(4)递归逐一的尝试不同的取值。
//判断是否是一个合法的全排列
bool isAnArrangement(vector<int>solution, vector<int>input)
{
bool result = true;
if (solution.size() == input.size())
{
sort(solution.begin(), solution.end());
sort(input.begin(), input.end());
for (int i = 0; i < input.size(); ++i)
{
if (input[i] != solution[i])
{
result = false;
return result;
}
}
}
else
{
result = false;
}
return result;
}
void backtrack(vector<int>solution, vector<int>input)
{
bool isSolution = isAnArrangement(solution, input);
if (isSolution)
{
copy(solution.begin(), solution.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return;
}
else
{
//构造候选解
vector<int>candidates(input);
for (auto itr1 = solution.begin(); itr1 < solution.end();++itr1)
{
auto itr2 = find(candidates.begin(), candidates.end(), *itr1);
if (itr2 != candidates.end())
{
candidates.erase(itr2);
}
}
//应注意去重
sort(candidates.begin(), candidates.end());
auto itr = unique(candidates.begin(), candidates.end());
candidates.resize(itr - candidates.begin());
for (int i = 0; i < candidates.size();++i)
{
int value = candidates[i];
vector<int>solution1(solution);//这里应注意是备份当前的状态进行尝试,不是直接更改当前的状态
solution1.push_back(value);
//solution.push_back(candidates[i]);
backtrack(solution1, input);
}
}
}
int main()
{
vector<int>solution;
vector<int>input = { 1,2,2,3};
backtrack(solution, input);
system("pause");
return 0;
}
