题意:给一个由\/字符组成的迷宫,问由这个迷宫形成的图有多少个闭合回路,并且输出最长一条有多长
理解:首先就从它给的样例那个图中,就可以看出来每条斜线代表了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; }