我发现我几乎每次遇到这种问题都会犯的一个错误是把行和列弄混了。所以下次遇到这种问题一定要注意把行和列与变量的对应的关系先明确下来,这样就不会每次都用那么多时间debug了。
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <assert.h>
#include <algorithm>
#include <math.h>
#include <ctime>
#include <functional>
#include <string.h>
#include <stdio.h>
#include <numeric>
#include <float.h>
using namespace std;
struct Grid {
bool half[2]; // for 0, half[0] is up+right, half[1] is down+left
// for 1, half[0] is up+left, half[1] is down+right
};
const int MX = 100;
int maze[MX][MX];
Grid mazeStatus[MX][MX];
int w, h;
void resetMaze() {
memset(maze, 0, sizeof(maze));
for (int i = 0; i<MX; i++)
for (int j = 0; j<MX; j++)
mazeStatus[i][j].half[0] = mazeStatus[i][j].half[1] = false;
}
bool validPoint(int i, int j) {
if (i < 0 || i >= h || j < 0 || j >= w)
return false;
return true;
}
// direction: 0-up, 1-down, 2-left, 3-right
pair<int, int> nextPoint(int i, int j, int &direction) {
pair<int, int> point;
if (maze[i][j] == 0) {
if (direction == 0) {
point.first = i;
point.second = j + 1;
direction = 2;
}
else if (direction == 1) {
point.first = i;
point.second = j - 1;
direction = 3;
}
else if (direction == 2) {
point.first = i + 1;
point.second = j;
direction = 0;
}
else {
point.first = i - 1;
point.second = j;
direction = 1;
}
}
else {
if (direction == 0) {
point.first = i;
point.second = j - 1;
direction = 3;
}
else if (direction == 1) {
point.first = i;
point.second = j + 1;
direction = 2;
}
else if (direction == 2) {
point.first = i - 1;
point.second = j;
direction = 1;
}
else {
point.first = i + 1;
point.second = j;
direction = 0;
}
}
return point;
}
int getHalf(int i, int j, int direction) {
if (maze[i][j] == 0) {
if (direction == 0 || direction == 3) return 0;
else return 1;
}
else {
if (direction == 0 || direction == 2) return 0;
else return 1;
}
}
bool browseMaze(int i, int j, int direction, bool first, int &length) {
int halfNum = getHalf(i, j, direction);
if (mazeStatus[i][j].half[halfNum]) {
if (first)
return false;
else
return true;
}
mazeStatus[i][j].half[halfNum] = true;
length++;
pair<int, int> np = nextPoint(i, j, direction);
if (!validPoint(np.first, np.second)) {
return false;
}
return browseMaze(np.first, np.second, direction, false, length);
}
int main() {
int T = 0;
while (cin >> w >> h) {
if (w == 0 && h == 0) break;
resetMaze();
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
char c; cin >> c;
if (c == '\\') {
maze[i][j] = 0;
}
else {
maze[i][j] = 1;
}
}
}
int circleNum = 0;
int maxLength = 0;
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
if (maze[i][j] == 0) {
int length = 0;
if (browseMaze(i, j, 0, true, length)) {
circleNum++;
maxLength = max(maxLength, length);
}
else {
mazeStatus[i][j].half[0] = false;
browseMaze(i, j, 3, true, length);
}
length = 0;
if (browseMaze(i, j, 1, true, length)) {
circleNum++;
maxLength = max(maxLength, length);
}
else {
mazeStatus[i][j].half[1] = false;
browseMaze(i, j, 2, true, length);
}
}
else {
int length = 0;
if (browseMaze(i, j, 0, true, length)) {
circleNum++;
maxLength = max(maxLength, length);
}
else {
mazeStatus[i][j].half[0] = false;
browseMaze(i, j, 2, true, length);
}
length = 0;
if (browseMaze(i, j, 1, true, length)) {
circleNum++;
maxLength = max(maxLength, length);
}
else {
mazeStatus[i][j].half[1] = false;
browseMaze(i, j, 3, true, length);
}
}
}
}
T++; cout << "Maze #" << T << ":" << endl;
if (circleNum > 0) {
cout << circleNum << " Cycles; the longest has length " << maxLength << "." << endl;
}
else {
cout << "There are no cycles." << endl;
}
cout << endl;
}
return 0;
}