今天闲着没事刷某音,看到如下问题。
想着最近学搜索和回溯算法,可以试试做一做,于是便有了以下代码。
#include <iostream>
using namespace std;
const int need = 3; //需要的路径数目
int p[30][30]; //棋盘通行点
int path[1000][2]; //路径点
int no[][2] = {{0, 1}, {0, 4}}; //不能走的点
int nt[][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}}; //可走的位移
int tx = 6, ty = 6, nocount = 2; //棋盘宽高,不能走的点的个数
int total = 0; //总路径数
int start[2] = {0, 0}; //启动点
void onfoundRoute()//查询到路线时调用的方法
{
for (size_t i = 0; i < tx * ty - nocount - 1; i++)
{
cout << "x:" << path[i][1] << " y:" << path[i][0] << "->";
}
cout << "done!" << endl<<endl;
}
void dfs(int step, int x, int y)
{
//所有找到的路线数量与需要的数量一致时完成
if (total == need)
return;
//走的步数遍布所有可走点时完成
if (step == tx * ty - nocount - 1)
{
onfoundRoute();
total++;
return;
}
int nx, ny;
for (size_t i = 0; i < 4; i++)
{
//产生下一步的点
nx = x + nt[i][1];
ny = y + nt[i][0];
//判断下一步的点是否在棋盘内
if (nx < 0 || nx >= tx)
continue;
if (ny < 0 || ny >= ty)
continue;
//判断下一步的点是否可走
if (p[ny][nx] == 1)
continue;
p[ny][nx] = 1;//记录下一步点已走
//记录路径
path[step + 1][0] = ny;
path[step + 1][1] = nx;
dfs(step + 1, nx, ny);//进入下一步点的进一步探索
//下一步点推测完后恢复当前点,为接下来的预测点做好准备
p[ny][nx] = 0;
path[step + 1][0] = -1;
path[step + 1][1] = -1;
}
}
//重置棋盘
void reset()
{
memset(p, 0, sizeof(p));
memset(path, -1, sizeof(path));
for (int i = 0; i < nocount; i++)
{
p[no[i][0]][no[i][1]] = 1;
}
total = 0;
}
int main()
{
for (size_t i = 0; i < ty; i++)
{
for (size_t j = 0; j < tx; j++)
{
reset();
if (p[i][j] == 1)
continue;
cout << "start as x:" << j << " y:" << i << endl;
start[0] = i;
start[1] = j;
path[0][0] = start[0];
path[0][1] = start[1];
p[i][j] = 1;
dfs(0, start[1], start[0]);
if (total == 0)
{
cout << "can not find a route!" << endl;
}
if (total == need)
break;
}
if (total == need)
break;
}
return 0;
}
运行结果如下:
start as x:0 y:0
x:0 y:0->x:0 y:1->x:0 y:2->x:0 y:3->x:0 y:4->x:0 y:5->x:1 y:5->x:1 y:4->x:1 y:3->x:1 y:2->x:1 y:1->x:2 y:1->x:2 y:0->x:3 y:0->x:3 y:1->x:3 y:2->x:2 y:2->x:2 y:3->x:2 y:4->x:2 y:5->x:3 y:5->x:3 y:4->x:3 y:3->x:4 y:3->x:4 y:4->x:4 y:5->x:5 y:5->x:5 y:4->x:5 y:3->x:5 y:2->x:4 y:2->x:4 y:1->x:5 y:1->done!
x:0 y:0->x:0 y:1->x:0 y:2->x:0 y:3->x:0 y:4->x:0 y:5->x:1 y:5->x:1 y:4->x:1 y:3->x:1 y:2->x:1 y:1->x:2 y:1->x:2 y:0->x:3 y:0->x:3 y:1->x:3 y:2->x:2 y:2->x:2 y:3->x:2 y:4->x:2 y:5->x:3 y:5->x:4 y:5->x:5 y:5->x:5 y:4->x:4 y:4->x:3 y:4->x:3 y:3->x:4 y:3->x:5 y:3->x:5 y:2->x:4 y:2->x:4 y:1->x:5 y:1->done!
x:0 y:0->x:0 y:1->x:0 y:2->x:0 y:3->x:0 y:4->x:0 y:5->x:1 y:5->x:1 y:4->x:1 y:3->x:1 y:2->x:1 y:1->x:2 y:1->x:2 y:0->x:3 y:0->x:3 y:1->x:3 y:2->x:2 y:2->x:2 y:3->x:3 y:3->x:3 y:4->x:2 y:4->x:2 y:5->x:3 y:5->x:4 y:5->x:5 y:5->x:5 y:4->x:4 y:4->x:4 y:3->x:5 y:3->x:5 y:2->x:4 y:2->x:4 y:1->x:5 y:1->done!
其中一条路径的示意图: