一个二维矩阵看成一个状态,按照题目的要求bfs就行了。判重用set。最最最最最最重要的是,这道题目居然神奇般的输出是纵坐标在前,横坐标在后。写代码的时间还没有理解题目的时间长==
#include #include #include #include #include #include #include #include #include using namespace std; const int maxn = 10; const int dx[] = {-1, 1, 0, 0}; const int dy[] = {0, 0, -1, 1}; const int dxx[] = {-2, 2, 0, 0}; const int dyy[] = {0, 0, -2, 2}; char G[10][10]; struct step{ int x1, y1, x2, y2; }; struct State{//状态类 char st[10][10]; vector ans; State(char a[10][10]){//因为输入是一个个字符,所以就不能用strcpy了 for (int i = 0; i < 7; i++){ for (int j = 0; j < 7; j++) st[i][j] = a[i][j]; st[i][7] = '\0';//将其变成字符串,方便为set写重载函数 } } State(){} bool operator < (const State &b) const{//set的重载函数 for(int i = 0; i < 7; i++){ if (strcmp(st[i], b.st[i])) return strcmp(st[i], b.st[i]) < 0; } return false; } }; set se; bool is_legal(int x, int y){//判断坐标是否合法 if (x>=0&&x<7&&y>=0&&y<7) return true; return false; } bool is_end(State a){//判断是不是到了最终状态 int ex = -1, ey = -1, cnt = 0; for (int i = 0; i < 7; i++) for (int j = 0; j < 7; j++){ if (a.st[i][j] == 'O'){ex = i;ey = j;} if (a.st[i][j] == 'o' || a.st[i][j] == 'O') cnt++; } if (cnt == 1 && ex != -1 && ey != -1) return true; return false; } void bfs(){ queue Q; set se; State src(G); se.insert(src); Q.push(src); bool fail = true; while (!Q.empty()){ State cur = Q.front(); Q.pop(); if (is_end(cur.st)){ fail = false; int i = 1; for (step it : cur.ans) printf("%d. (%d, %d) to (%d, %d)\n", i++, it.x1, it.y1, it.x2, it.y2); break; } for (int i = 0; i < 7; i++) for (int j = 0; j < 7; j++){ if (cur.st[i][j] == 'o' || cur.st[i][j] == 'O'){ for (int d = 0; d < 4; d++){ int x = i + dx[d], y = j + dy[d];//相邻的坐标 int xx = i + dxx[d], yy = j + dyy[d];//落地处坐标 if (is_legal(x, y)&&is_legal(xx, yy)){ if (cur.st[x][y]=='o'||cur.st[x][y]=='O'){ if (cur.st[xx][yy]=='e'||cur.st[xx][yy]=='E'){ State next(cur.st); if (cur.st[i][j] == 'o') next.st[i][j] = 'e'; else next.st[i][j] = 'E'; if (cur.st[x][y] == 'o') next.st[x][y] = 'e'; else next.st[x][y] = 'E'; if (cur.st[xx][yy] == 'e') next.st[xx][yy] = 'o'; else next.st[xx][yy] = 'O'; if (se.count(next.st)) continue; se.insert(next.st); for (step it : cur.ans) next.ans.push_back(it); next.ans.push_back(step{j + 1, i + 1, yy + 1, xx + 1}); Q.push(next); } } } } } } } if (fail) printf("No solution.\n"); } int main() { //freopen("1.txt", "r", stdin); int T, Case = 1; scanf("%d\n", &T); while (T--){ for (int i = 0; i < 7; i++) for (int j = 0; j < 7; j++){ G[i][j] = getchar(); getchar(); } printf("Dataset %d:\n", Case++); bfs(); } return 0; }