题意:给一个由\/字符组成的迷宫,问由这个迷宫形成的图有多少个闭合回路,并且输出最长一条有多长
理解:首先就从它给的样例那个图中,就可以看出来每条斜线代表了2个格子,然后闭合回路中最大长度就是闭合回路中格子的格子的个数。
那么,输入这个图之后对每个坐标乘2进行放大建图就行了。
然后就是暴力跑dfs,跑一个图,暴力标记计数就行,然后需要判断下终点是否和起点相邻,然后判断这个格子数还必须大于4,否则可能是边缘情况。
dfs的时候要分上下左右走和斜着走,就是斜着走的需要判断下是否能走,有一个问题是判断斜着走必须是直着走,不能有任何阻挡,即使只有一格阻挡也不行,某些边界条件可能会使其越出界(我猜的),wa几发确实不懂,把这里改了就过了,也有可能是记录终点的时候瞎跑可能会撞到起点临近点吧,我没想到什么hack的情况,如果有人能想到请麻烦给我讲下。
CODE:
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn = 300;
int n,m;
int cnt; ///记录最长回路
bool vis[maxn][maxn]; ///标记
char s[maxn][maxn]; ///输入用
char maze[maxn][maxn]; ///转换用
int dir[8][2] = {0,1,0,-1,1,0,-1,0, ///上下左右走
-1,-1,1,-1,1,1,-1,1}; ///斜着走
int last_x,last_y; ///一条路径的终点
void chg(int row) ///转换图
{
for(int i = 1;i <= m;i++)
{
int pox = 2*row,poy = 2*i;
if(s[row][i] == '\\')
{
maze[pox-1][poy-1] = '\\';
maze[pox][poy] = '\\';
maze[pox-1][poy] = ' ';
maze[pox][poy-1] = ' ';
}
else if(s[row][i] == '/')
{
maze[pox-1][poy] = '/';
maze[pox][poy-1] = '/';
maze[pox-1][poy-1] = ' ';
maze[pox][poy] = ' ';
}
}
}
bool legal(int x,int y) ///走的点是否合法
{
if(x > 0 && y > 0 && x <= 2*n && y <= 2*m && maze[x][y] != '\\' && maze[x][y] != '/' && !vis[x][y])
return true;
return false;
}
bool ispass(int x,int y,int i) ///斜着走的时候不能有任何阻挡,不然不能走
{
int x1 = x, y1 = y+dir[i][1];
int x2 = x+dir[i][0],y2 = y;
if(i == 4 || i == 6) ///左上和右下走
{
if(maze[x1][y1] == '\\' && maze[x2][y2] == '\\')
return true;
}
else
{
if(maze[x1][y1] == '/' && maze[x2][y2] == '/')
return true;
}
return false;
}
void dfs(int x,int y)
{
vis[x][y] = true;
for(int i = 0;i < 8;i++)
{
int tx = x+dir[i][0];
int ty = y+dir[i][1];
if(i < 4)
{
if(legal(tx,ty))
{
cnt++;
last_x = tx; ///记录终点位置
last_y = ty;
dfs(tx,ty);
}
}
else
{
if(legal(tx,ty) && ispass(x,y,i)) ///斜着走的点合法后还要判断是否是无阻挡直走的
{
cnt++;
last_x = tx;
last_y = ty;
dfs(tx,ty);
}
}
}
}
int main(void)
{
int T = 1;
while(scanf("%d%d",&m,&n) && (n||m))
{
memset(vis,false,sizeof vis);
memset(maze,0,sizeof maze);
for(int i = 1;i <= n;i++)
{
scanf("%s",s[i]+1);
chg(i);
}
int ans = -1;
int c = 0;
bool ch = false;
for(int i = 1;i <= 2*n;i++)
{
for(int j = 1;j <= 2*m;j++)
{
if(maze[i][j] == ' ' && !vis[i][j])
{
cnt = 1;
dfs(i,j);
bool flag = false;
for(int k = 0;k < 8;k++) ///终点是否与起点相邻
{
int tx = last_x+dir[k][0];
int ty = last_y+dir[k][1];
if(tx == i && ty == j)
{
flag = true;
}
}
if(flag && cnt >= 4) ///根据边界情况回路的格子数必须大于4
{
ans = max(ans,cnt);
c++;
ch = true;
}
}
}
}
printf("Maze #%d:\n",T++);
if(ch)
{
printf("%d Cycles; the longest has length %d.\n\n", c, ans);
}
else
{
printf("There are no cycles.\n\n");
}
}
return 0;
}
本文介绍了一种算法,用于计算由斜杠字符组成的迷宫中的闭合回路数量及最长闭合回路的长度。通过将迷宫放大并转换为更详细的网格图,利用深度优先搜索(DFS)来遍历所有可能的路径。
3452

被折叠的 条评论
为什么被折叠?



