传送门UVa 705 - Slash Maze
昨天这道题没写出来,觉都没睡好。
想了很久,觉得我的思路是一点问题都没有的,但是输出就是不对。
刚才又看了一遍,只好单步调试了一下。才发现。。我一直把坐标当成直角坐标系了!!!
本来x是行,y是列,x + 1就是下一行。我偏偏以为x + 1是水平+1.。。。。。。。。。然后我就悲剧了。
这题没思路,后来看到一个神一般的办法,把图像扩大两倍,然后斜线就可以用1表示!!!0的地方就是可以走的地方!
Sample Input的部分画出来大概是这个样子。大家看看就好。。。
ORZ。给想出这个办法的人跪了。涨姿势
接下来就好办了,上下左右四个方向必走,斜线看情况。
好题啊。。。
因为判断能否斜着走的时候要区分\ and /,所以我用-1表示前者,1表示后者。
UVa挂了,不过代码应该没错。先贴上。
-------------------------------------------------------------------------------------------------------------
AC.
#include <cstdio> #include <cstring> using namespace std; int cycle, maxLen, flag, len, W, H; int maze[200][200]; void DFS(int x, int y); int main() { //freopen("input.txt", "r", stdin); int w, h, i, j, k, cases = 1; char ch; while (scanf("%d%d%*c", &w, &h)) { memset(maze, 0, sizeof(maze)); W = 2 * w; H = 2 * h; k = cycle = maxLen = 0; if (w + h == 0) break; for (i = 1; i <= H; i += 2, getchar()) for (j = 1; j <= W; j += 2) { if ((ch = getchar()) == '\\') { maze[i][j] = -1; maze[i + 1][j + 1] = -1; } else { maze[i][j + 1] = 1; maze[i + 1][j] = 1; } } for (i = 1; i <= H; i++) for (j = 1; j <= W; j++) if (maze[i][j] == 0) { flag = 1; len = 0; DFS(i, j); cycle += flag; if (len > maxLen && flag) maxLen = len; } printf("Maze #%d:\n", cases++); if (cycle) printf("%d Cycles; the longest has length %d.\n\n", cycle, maxLen); else printf("There are no cycles.\n\n"); } return 0; } void DFS(int x, int y) { if (x == 0 || y == 0 || x == H + 1 || y == W + 1) //说明到了边界, 不是一个圈 { flag = 0; return; } if (maze[x][y] == -1 || maze[x][y] == 1 || maze[x][y] == 2) return; maze[x][y] = 2; len++; DFS(x - 1, y);//先搜索四个方向,不管怎样 DFS(x + 1, y); DFS(x, y - 1); DFS(x, y + 1); //因为有可能走斜线,要分情况。 //1.能否走左下:如果左,下都是-1,即\,说明被挡住了, 不能走。反之能。同理可得其他的。 if (maze[x - 1][y] == -1 && maze[x][y - 1] == -1) DFS(x - 1, y - 1); if (maze[x - 1][y] == 1 && maze[x][y + 1] == 1) DFS(x - 1, y + 1); if (maze[x + 1][y] == 1 && maze[x][y - 1] == 1) DFS(x + 1, y - 1); if (maze[x][y + 1] == -1 && maze[x + 1][y] == -1) DFS(x + 1, y + 1); }