奔跑的邮件:邮政车每天都要把各个邮筒里的邮件都拉走,但它只经过每一个邮筒一次,最后返回起点。
要求:
(1)画出邮筒的分布图,比如以矩阵表示,6*6的大小;
(2)规定起点,并给出部分路线,不超过五条;
(3)根据上述条件,画出完整路线图。说明:可以上下左右移动,但不能对角线行走。
这个程序有一丢丢bug,我就不在这里改了(当然我是在自己的程序里改了的\滑稽),相信聪明睿智灵敏如你一定能看出来,大家有兴趣可以de一下🌚
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int MAXN = 10 * 10 + 5;
// 邻接矩阵建图
int g[MAXN][MAXN];
bool vis[MAXN]; // dfs时判断路径是否访问过
int dx[] = {-1, 1, 0, 0}; // 上下左右的x坐标变化量
int dy[] = {0, 0, -1, 1}; // 上下左右y左边变化量
// 深度优先搜索,找到s->e的路径,要求满足经过的点数w是36
// path
bool dfs(int s, int e, int path[], int deep)
{
if (s == e)
{
// 找到一条完整的路径
if (deep != 37)
{
// 未走完所有点
return false;
}
// 输出路径
for (int i = 0; i < deep; ++i)
{
cout << "(" << path[i] / 10 << ", " << path[i] % 10 << ") ";
}
cout << endl;
return true;
}
// 搜索过程中已访问过
if (vis[s])
{
return false;
}
// 标记访问过s
vis[s] = true;
// 起点的x,y
int sx = s / 10;
int sy = s % 10;
for (int i = 0; i < 4; ++i)
{
// 上下左右4个点
int nx = sx + dx[i];
int ny = sy + dy[i];
int to = nx*10+ny;
// 越界检查和判断是否有边
if (1 <= nx && nx <= 6 && 1 <= ny && ny <= 6 && g[s][to] != 0)
{
path[deep] = to;
if (dfs(to, e, path, deep+1))
return true;
}
}
// 取消标记
vis[s] = false;
return false;
}
// 是否是指定边的起始点,是的话它可以有入边
bool zhidingStart[MAXN];
// 是否是指定边的终点,是的话它可以有出边
bool zhidingEnd[MAXN];
// 是否是指定边的中间点
bool zhiding[MAXN];
int main()
{
int E, n, x, y;
cout << "输入指定边条数:";
cin >> E;
for (int i = 0; i < E; ++i)
{
cout << "请输入第" << i + 1 << "条边顶点数:";
cin >> n;
cout << "输入" << n << "个坐标:";
int pre = -1;
for (int j = 1; j <= n; ++j)
{
cin >> x >> y;
// 将二维转换为一维
int s = x * 10 + y;
if (j == 1)
{
zhidingStart[s] = true;
}
if (j == n)
{
zhidingEnd[s] = true;
}
if (j != 1 && j != n)
{
zhiding[s] = true;
}
if (pre != -1)
{
// 添加边pre->s,也就是这个边中上一个点到这个点
g[pre][s] = 1;
}
pre = s;
}
}
for (x = 1; x <= 6; ++x)
{
for (y = 1; y <= 6; ++y)
{
int s = x * 10 + y;
if (zhiding[s] || zhidingStart[s])
{
// 如果s在指定边上(除了指定的终点),不能到其它点
continue;
}
for (int i = 0; i < 4; ++i)
{
int nx = x + dx[i];
int ny = y + dy[i];
if (1 <= nx && nx <= 6 && 1 <= ny && ny <= 6)
{
int e = nx * 10 + ny;
if (zhiding[e] || zhidingEnd[e])
{
// 如果e在指定边(除了指定的起点),其他点不能到e
continue;
}
// s->e
g[s][e] = 1;
}
}
}
}
cout << "请输入指定的起点坐标:";
cin >> x >> y;
int s = x * 10 + y;
// 存一下起点
int e = s;
int path[100];
path[0] = s;
int deep = 1;
for (int i = 0; i < 4; ++i)
{
// 上下左右4个点
int nx = x + dx[i];
int ny = y + dy[i];
int to = nx*10+ny;
// 越界检查和判断是否有边
if (1 <= nx && nx <= 6 && 1 <= ny && ny <= 6 && g[s][to] != 0)
{
path[deep] = to;
if (dfs(to, e, path, deep+1))
return 0;
}
}
cout << "没有路" << endl;
return 0;
}