一个二维矩阵看成一个状态,按照题目的要求bfs就行了。判重用set。最最最最最最重要的是,这道题目居然神奇般的输出是纵坐标在前,横坐标在后。写代码的时间还没有理解题目的时间长==
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <queue>
#include <map>
#include <set>
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<step> 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<State> 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<State> Q;
set<State> 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;
}