标签:
#include<iostream>
#include<vector>
#include<iterator>
#include<algorithm>
using namespace std;
/*
将1-n全排列,目前到了从左到右的step位
box:从左到右存储
flags:1-n哪些已经用了
*/
void dfs(vector<int> & box, vector<bool> & flags, int step, int n)
{
if (step == n) //如果当前到n,说明0~n-1已经存了1~n,停止搜索
{
ostream_iterator<int> o_iter(cout, "");
copy(box.begin(), box.end(), o_iter);
cout << endl;
return;
}
//此时站在第step位(从左到右),将没使用的数按1~3尝试
for (int i = 1; i <= n; ++i)
{
if (flags[i - 1] == false) //如果这个数是未使用的
{
//开始尝试使用
box[step] = i;
flags[i - 1] = true;
//在这种使用方式下,处理下一位
dfs(box, flags, step + 1, n);
//把数放回,尝试下一个数
flags[i - 1] = false;
}
}
}
int main(void)
{
int n = 3; //输入1-3的全排列
vector<int> box(n);
vector<bool> flags(n, false);
dfs(box, flags, 0, n); //从左边第一位开始尝试
return 0;
}
//深度优先搜索的基本模型
void dfs(int step)
{
判断边界
尝试每一种可能 for(i = 1; i <= n; ++i)
{
继续下一步 dfs(step + 1);
}
返回
}
#include<iostream>
#include<vector>
using namespace std;
void dfs(vector<int> & box, vector<bool> & flags, int step, int n, int & total)
{
if (step == n)
{
int a = box[0] * 100 + box[1] * 10 + box[2];
int b = box[3] * 100 + box[4] * 10 + box[5];
int c = box[6] * 100 + box[7] * 10 + box[8];
if (a + b == c) //判断等式是否满足
{
cout << box[0] << box[1] << box[2] << ‘+‘
<< box[3] << box[4] << box[5] << ‘=‘
<< box[6] << box[7] << box[8] << endl;
++total;
}
return;
}
for (int i = 1; i <= n; ++i)
{
if (flags[i - 1] == false)
{
//开始尝试使用
box[step] = i;
flags[i - 1] = true;
//在这种使用方式下,处理下一位
dfs(box, flags, step + 1, n, total);
//把数放回,尝试下一个数
flags[i - 1] = false;
}
}
}
int main(void)
{
int n = 9; //输入1-9的全排列,但是要使得???+???=???等式成立
vector<int> box(n);
vector<bool> flags(n, false);
int total = 0; //设置变量用于存储所有情况
dfs(box, flags, 0, n, total); //从左边第一位开始尝试
cout << total / 2 << endl;
return 0;
}
#include<iostream>
#include<vector>
#include<algorithm>
#include<climits>
#include<iterator>
using namespace std;
struct Point
{
int x;
int y;
};
void dfs(vector<vector<int>> & map, vector<vector<bool>> & flags, //地图及地图标记
Point curr, Point end, //当前位置及目的位置
int step, vector<Point> & path, int & min, vector<Point> & min_path) //当前步长和当前路径,以及最短长度和最短路径
{
if (curr.x == end.x && curr.y == end.y)
{
if (step < min)
{
min = step;
min_path.resize(path.size());
copy(path.begin(), path.end(), min_path.begin());
}
return;
}
static const vector<vector<int>> next = {
{0, 1}, //向右
{1, 0}, //向下
{0, -1}, //向左
{-1, 0} //向上
};
for (const auto & direction : next)
{
//计算下一个点的坐标
Point trypoint;
trypoint.x = curr.x + direction[0];
trypoint.y = curr.y + direction[1];
//判断是否越界
if (trypoint.x < 0 || trypoint.x >= map.size()
|| trypoint.y < 0 || trypoint.y >= map[0].size())
continue;
if (map[trypoint.x][trypoint.y] == 0 && flags[trypoint.x][trypoint.y] == false)
{
//该点不是障碍且在路径中
flags[trypoint.x][trypoint.y] = true; //标记这个点已经走过
path.push_back(trypoint);
dfs(map, flags, trypoint, end, step + 1, path, min, min_path); //下一个点
path.pop_back();
flags[trypoint.x][trypoint.y] = false; //尝试结束,取消这个点的标记
}
}
}
int main(void)
{
int rows = 5; //行数
int cols = 4; //列数
vector<vector<int>> map = {
{0, 0, 1, 0},
{0, 0, 0, 0},
{0, 0, 1, 0},
{0, 1, 0, 0},
{0, 0, 0, 1},
};
vector<vector<bool>> flags(map.size(), vector<bool>(map[0].size(), false)); //行走标记
//(向下为x,向右为y)
//起点
Point start;
start.x = 0;
start.y = 0;
//终点
Point end;
end.x = 3;
end.y = 2;
vector<Point> path; //搜索过程中尝试保存的路径
path.push_back(start); //路径的起点一定是(0, 0)
vector<Point> min_path; //最短路径
int min = INT_MAX; //最短路径长度
dfs(map, flags, start, end, 0, path, min, min_path); //从起点开始搜索
cout << min << endl;
for (auto iter = min_path.begin(); iter != min_path.end(); ++iter)
{
cout << ‘(‘ << iter->x << ‘,‘ << iter->y << ‘)‘;
if (iter == min_path.end() - 1)
break;
cout << " ==> ";
}
cout << endl;
//地图和路线的打印
ostream_iterator<int> o_iter(cout, " ");
cout << "原图" << endl;
for (const auto & line : map)
{
copy(line.begin(), line.end(), o_iter);
cout << endl;
}
cout << "走起" << endl;
for (const auto & point : min_path)
map[point.x][point.y] = 2;
for (const auto & line : map)
{
copy(line.begin(), line.end(), o_iter);
cout << endl;
}
return 0;
}
#include<iostream>
#include<vector>
#include<iterator>
using namespace std;
struct Point
{
int x;
int y;
int last; //上一个点,从哪个点来的,对第一个点无意义
};
int main(void)
{
int rows = 5; //行数
int cols = 4; //列数
vector<vector<int>> map = {
{0, 0, 1, 0},
{0, 0, 0, 0},
{0, 0, 1, 0},
{0, 1, 0, 0},
{0, 0, 0, 1},
};
static const vector<vector<int>> next = {
{ 0, 1 }, //向右
{ 1, 0 }, //向下
{ 0, -1 }, //向左
{ -1, 0 } //向上
};
vector<vector<bool>> flags(map.size(), vector<bool>(map[0].size(), false)); //行走标记
//(向下为x,向右为y)
//起点
Point start;
start.x = 0;
start.y = 0;
//终点
Point end;
end.x = 3;
end.y = 2;
vector<Point> search; //不用queue是因为要还原路径
start.last = 0;
search.push_back(start);
int header = 0;
bool isfind = false;
while (header != search.size() && !isfind) //队列不为空
{
for (const auto & direction : next)
{
Point trypoint;
trypoint.x = search[header].x + direction[0];
trypoint.y = search[header].y + direction[1];
if (trypoint.x < 0 || trypoint.x >= map.size()
|| trypoint.y < 0 || trypoint.y >= map[0].size()) //判断是否越界
continue;
if (map[trypoint.x][trypoint.y] == 0 && flags[trypoint.x][trypoint.y] == false)
{
//该点不是障碍且在路径中
//宽度优先搜索每个点只入队一次,不需要将flags还原
flags[trypoint.x][trypoint.y] = true;
trypoint.last = header;
search.push_back(trypoint);
}
if (trypoint.x == end.x && trypoint.y == end.y)
{
//广度优先搜索找到一条路径就停止
isfind = true;
break;
}
}
++header;
}
//严格来说必须判断isfind才能确定是不是找到之后才跳出来的
vector<Point> path;
int curr_index = search.size() - 1; //如果是找到之后跳出来,那么最后一个点一定是终点
while (true)
{
path.push_back(search[curr_index]);
if (curr_index == search[curr_index].last) //已到起点,跳出
break;
curr_index = search[curr_index].last;
}
for (auto iter = path.rbegin(); iter != path.rend(); ++iter)
{
cout << ‘(‘ << iter->x << ‘,‘ << iter->y << ‘)‘;
if (iter == path.rend() - 1)
break;
cout << " ==> ";
}
cout << endl;
//地图和路线的打印
ostream_iterator<int> o_iter(cout, " ");
cout << "原图" << endl;
for (const auto & line : map)
{
copy(line.begin(), line.end(), o_iter);
cout << endl;
}
cout << "走起" << endl;
for (const auto & point: path)
map[point.x][point.y] = 2;
for (const auto & line : map)
{
copy(line.begin(), line.end(), o_iter);
cout << endl;
}
return 0;
}
#include<iostream>
#include<vector>
#include<string>
#include<queue>
using namespace std;
struct Point
{
int x;
int y;
};
int getnum(const vector<string> & map, int i, int j)
{
//在某个点放置炸弹能够消灭的敌人数
int sum = 0;
int x = i;
int y = j;
while (map[x][y] != ‘#‘) //向下
{
if (map[x][y] == ‘G‘) //是敌人
++sum;
++x;
}
x = i;
y = j;
while (map[x][y] != ‘#‘) //向上
{
if (map[x][y] == ‘G‘)
++sum;
--x;
}
x = i;
y = j;
while (map[x][y] != ‘#‘) //向右
{
if (map[x][y] == ‘G‘)
++sum;
++y;
}
x = i;
y = j;
while (map[x][y] != ‘#‘) //向左
{
if (map[x][y] == ‘G‘)
++sum;
--y;
}
return sum;
}
int main(void)
{
vector<string> map = {
"#############",
"#GG.GGG#GGG.#",
"###.#G#G#G#G#",
"#.......#..G#",
"#G#.###.#G#G#",
"#GG.GGG.#.GG#",
"#G#.#G#.#.#.#", //#G#.#G#.#.###,为了测试修改
"##G...G.....#",
"#G#.#G###.#G#",
"#...G#GGG.GG#",
"#G#.#G#G#.#G#",
"#GG.GGG#G.GG#",
"#############"
};
vector<vector<bool>> flags(map.size(), vector<bool>(map[0].size(), false));
static const vector<vector<int>> next = {
{ 0, 1 }, //向右
{ 1, 0 }, //向下
{ 0, -1 }, //向左
{ -1, 0 } //向上
};
queue<Point> search;
search.push({ 3, 3 }); //队首,起始位置
//统计最多的敌人数和坐标,假设起点最大,再四方广搜
int max_count = getnum(map, 3, 3);
int max_x = 3;
int max_y = 3;
//两重循环枚举每一点
while (!search.empty())
{
for (const auto & direction : next)
{
Point trypoint;
trypoint.x = search.front().x + direction[0];
trypoint.y = search.front().y + direction[1];
if (trypoint.x < 0 || trypoint.x >= map.size()
|| trypoint.y < 0 || trypoint.y >= map[0].size()) //判断是否越界
continue;
if (map[trypoint.x][trypoint.y] == ‘.‘ && flags[trypoint.x][trypoint.y] == false)
{
//该点不是障碍并且没走过
flags[trypoint.x][trypoint.y] = true; //没走过就走起
search.push(trypoint);
int sum = getnum(map, trypoint.x, trypoint.y);
if (sum > max_count)
{
max_count = sum;
max_x = trypoint.x;
max_y = trypoint.y;
}
}
}
search.pop(); //当前点扩展完,出队
}
cout << ‘(‘ << max_x << ‘,‘ << max_y << ")==>" << max_count << endl;
return 0;
}
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int getnum(const vector<string> & map, int i, int j)
{
//在某个点放置炸弹能够消灭的敌人数
int sum = 0;
int x = i;
int y = j;
while (map[x][y] != ‘#‘) //向下
{
if (map[x][y] == ‘G‘) //是敌人
++sum;
++x;
}
x = i;
y = j;
while (map[x][y] != ‘#‘) //向上
{
if (map[x][y] == ‘G‘)
++sum;
--x;
}
x = i;
y = j;
while (map[x][y] != ‘#‘) //向右
{
if (map[x][y] == ‘G‘)
++sum;
++y;
}
x = i;
y = j;
while (map[x][y] != ‘#‘) //向左
{
if (map[x][y] == ‘G‘)
++sum;
--y;
}
return sum;
}
void dfs(const vector<string> & map, vector<vector<bool>> & flags, int x, int y,
int & max_x, int & max_y, int & max_count) //记录最优值
{
//统计当前点
int sum = getnum(map, x, y);
if (sum > max_count)
{
max_count = sum;
max_x = x;
max_y = y;
}
static const vector<vector<int>> next = {
{ 0, 1 }, //向右
{ 1, 0 }, //向下
{ 0, -1 }, //向左
{ -1, 0 } //向上
};
//从该点开始深度搜索每个方向
for (const auto & direction : next)
{
int try_x = x + direction[0];
int try_y = y + direction[1];
if (try_x < 0 || try_x >= map.size() || try_y < 0 || try_y >= map[0].size())
continue; //判断是否越界
if (map[try_x][try_y] == ‘.‘ && flags[try_x][try_y] == false)
{
//该点不是障碍并且还没走过
flags[try_x][try_y] = true;
dfs(map, flags, try_x, try_y, max_x, max_y, max_count); //尝试下一点
//因为没有还原,所以终点就是能走到的点全部都标记了
}
}
}
int main(void)
{
vector<string> map = {
"#############",
"#GG.GGG#GGG.#",
"###.#G#G#G#G#",
"#.......#..G#",
"#G#.###.#G#G#",
"#GG.GGG.#.GG#",
"#G#.#G#.#.#.#", //#G#.#G#.#.###,为了测试修改
"##G...G.....#",
"#G#.#G###.#G#",
"#...G#GGG.GG#",
"#G#.#G#G#.#G#",
"#GG.GGG#G.GG#",
"#############"
};
vector<vector<bool>> flags(map.size(), vector<bool>(map[0].size(), false));
//统计最多的敌人数和坐标,假设起点最大,再四方广搜
int max_count = getnum(map, 3, 3);
int max_x = 3;
int max_y = 3;
dfs(map, flags, 3, 3, max_x, max_y, max_count);
cout << ‘(‘ << max_x << ‘,‘ << max_y << ")==>" << max_count << endl;
return 0;
}
#include<iostream>
#include<vector>
#include<queue>
#include<iomanip>
using namespace std;
struct Point
{
int x;
int y;
};
void bfs(vector<vector<int>> & map, vector<vector<bool>> & flags, int x, int y, int color)
{
static const vector<vector<int>> next = {
{ 0, 1 }, //向右
{ 1, 0 }, //向下
{ 0, -1 }, //向左
{ -1, 0 } //向上
};
queue<Point> search;
search.push({ x, y }); //起始坐标
flags[x][y] = true;
while (!search.empty())
{
for (const auto & direction : next)
{
Point trypoint;
trypoint.x = search.front().x + direction[0];
trypoint.y = search.front().y + direction[1];
if (trypoint.x < 0 || trypoint.x >= map.size()
|| trypoint.y < 0 || trypoint.y >= map[0].size())
continue; //判断是否越界
if (map[trypoint.x][trypoint.y] >= 1 &&
map[trypoint.x][trypoint.y] <= 9 &&
flags[trypoint.x][trypoint.y] == false)
{
//每个点只入队一次,所以需要标记
flags[trypoint.x][trypoint.y] = true;
search.push(trypoint);
}
}
//当前点处理完毕,染色,出队
map[search.front().x][search.front().y] = color;
search.pop();
}
}
int main(void)
{
vector<vector<int>> map = {
{1, 2, 1, 0, 0, 0, 0, 0, 2, 3},
{3, 0, 2, 0, 1, 2, 1, 0, 1, 2},
{4, 0, 1, 0, 1, 2, 3, 2, 0, 1},
{3, 2, 0, 0, 0, 1, 2, 4, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 5, 3, 0},
{0, 1, 2, 1, 0, 1, 5, 4, 3, 0},
{0, 1, 2, 3, 1, 3, 6, 2, 1, 0},
{0, 0, 3, 4, 8, 9, 7, 5, 0, 0},
{0, 0, 0, 3, 7, 8, 6, 0, 1, 2},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0}
};
vector<vector<bool>> flags(map.size(), vector<bool>(map[0].size(), false));
//输出原始地图
for (const auto & line : map)
{
for (const auto & point : line)
cout << setw(3) << point;
cout << endl;
}
//给出一个降落点就得出一个岛屿
//遍历整个地图,把所有可降落点搜索一次并标记,找出所有岛屿
int color = -1;
for (int i = 0; i < map.size(); ++i)
{
for (int j = 0; j < map[i].size(); ++j)
{
if (map[i][j] >= 1 && map[i][j] <= 9) //被填充的肯定是-1、-2、-3……
{
bfs(map, flags, i, j, color);
--color;
}
}
}
//输出染色地图
cout << "共有" << (-color - 1) << "个岛屿" << endl;
for (const auto & line : map)
{
for (const auto & point : line)
cout << setw(3) << point;
cout << endl;
}
return 0;
}
#include<iostream>
#include<vector>
#include<iomanip>
using namespace std;
void dfs(vector<vector<int>> & map, vector<vector<bool>> & flags, int x, int y, int color)
{
static const vector<vector<int>> next = {
{ 0, 1 }, //向右
{ 1, 0 }, //向下
{ 0, -1 }, //向左
{ -1, 0 } //向上
};
map[x][y] = color; //对当前点进行着色
for (const auto & direction : next)
{
int tx = x + direction[0];
int ty = y + direction[1];
if (tx < 0 || tx >= map.size() || ty < 0 || ty >= map[0].size())
continue; //判断是否越界
if (map[tx][ty] >= 1 && map[tx][ty] <= 9 && flags[tx][ty] == false)
{
//是陆地并且还没搜索过
flags[tx][ty] = true;
dfs(map, flags, tx, ty, color);
}
}
}
int main(void)
{
vector<vector<int>> map = {
{1, 2, 1, 0, 0, 0, 0, 0, 2, 3},
{3, 0, 2, 0, 1, 2, 1, 0, 1, 2},
{4, 0, 1, 0, 1, 2, 3, 2, 0, 1},
{3, 2, 0, 0, 0, 1, 2, 4, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 5, 3, 0},
{0, 1, 2, 1, 0, 1, 5, 4, 3, 0},
{0, 1, 2, 3, 1, 3, 6, 2, 1, 0},
{0, 0, 3, 4, 8, 9, 7, 5, 0, 0},
{0, 0, 0, 3, 7, 8, 6, 0, 1, 2},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0}
};
vector<vector<bool>> flags(map.size(), vector<bool>(map[0].size(), false));
//输出原始地图
for (const auto & line : map)
{
for (const auto & point : line)
cout << setw(3) << point;
cout << endl;
}
//给出一个降落点就得出一个岛屿
//遍历整个地图,把所有可降落点搜索一次并标记,找出所有岛屿
int color = -1;
for (int i = 0; i < map.size(); ++i)
{
for (int j = 0; j < map[i].size(); ++j)
{
if (map[i][j] >= 1 && map[i][j] <= 9) //被填充的肯定是-1、-2、-3……
{
flags[i][j] = true;
dfs(map, flags, i, j, color);
--color;
}
}
}
//输出染色地图
cout << "共有" << (-color - 1) << "个岛屿" << endl;
for (const auto & line : map)
{
for (const auto & point : line)
cout << setw(3) << point;
cout << endl;
}
return 0;
}
#include<iostream>
#include<vector>
using namespace std;
enum PIPE_TYPE {
TREE, L_UR, L_RD, L_DL, L_LU, I_H, I_V
};
enum IN_DIRECTION {
IN_LEFT, IN_UP, IN_RIGHT, IN_DOWN
};
struct Point
{
int x;
int y;
};
void dfs(const vector<vector<PIPE_TYPE>> & map, vector<vector<bool>> & flags,
int x, int y, IN_DIRECTION direction, vector<Point> & path)
{
if (x == map.size() - 1 && y == map[0].size())
{
for (const auto & point : path)
cout << ‘(‘ << point.x << ‘,‘ << point.y << ‘)‘ << ‘ ‘;
cout << endl;
return;
}
//判断是否越界
if (x < 0 || x >= map.size() || y < 0 || y >= map[0].size())
return;
//判断这个管道是否已经使用过
if (flags[x][y] == true)
return;
flags[x][y] = true; //标记使用当前管道
path.push_back({ x, y });
//如果当前是直管
if (map[x][y] == I_H || map[x][y] == I_V)
{
//进水口在左边,只能使用I_H情况
if (direction == IN_LEFT)
dfs(map, flags, x, y + 1, IN_LEFT, path);
//进水口在上边,只能使用I_V情况
else if (direction == IN_UP)
dfs(map, flags, x + 1, y, IN_UP, path);
//进水口在右边,只能使用I_H情况
else if (direction == IN_RIGHT)
dfs(map, flags, x, y - 1, IN_RIGHT, path);
//进水口在下面,只能使用I_V情况
else
dfs(map, flags, x - 1, y, IN_DOWN, path);
}
//如果当前是弯管
else
{
if (direction == IN_LEFT)
{
dfs(map, flags, x + 1, y, IN_UP, path); //L_DL
dfs(map, flags, x - 1, y, IN_DOWN, path); //L_LU
}
else if (direction == IN_UP)
{
dfs(map, flags, x, y + 1, IN_LEFT, path); //L_UR
dfs(map, flags, x, y - 1, IN_RIGHT, path); //L_LU
}
else if (direction == IN_RIGHT)
{
dfs(map, flags, x - 1, y, IN_DOWN, path); //L_UR
dfs(map, flags, x + 1, y, IN_UP, path); //L_RD
}
else
{
dfs(map, flags, x, y + 1, IN_LEFT, path); //L_RD
dfs(map, flags, x, y - 1, IN_RIGHT, path); //L_DL
}
}
flags[x][y] = false; //取消标记
path.pop_back(); //将当前尝试的坐标出栈
}
int main(void)
{
vector<vector<PIPE_TYPE>> map = {
{I_H, L_DL, I_H, L_DL},
{L_UR, I_H, L_DL, TREE},
{L_RD, L_DL, I_H, L_UR},
{I_V, L_UR, L_UR, I_H},
{L_UR, I_H, I_H, L_LU}
};
vector<vector<bool>> flags(map.size(), vector<bool>(map[0].size(), false));
vector<Point> path;
dfs(map, flags, 0, 0, IN_LEFT, path);
return 0;
}
标签:
原文地址:http://blog.csdn.net/jasschow/article/details/51615838