一开始用的单向dfs 毫无意外超时了 只得了60分
后面搜了一下,发现要用双向dfs ,试了一下终于过了
我的思路:
①状态转换还是用数组进行四个方向的操作
int dx[4]={0, -1, 0, 1}, dy[4]={-1, 0, 1, 0};
②用map<string, int> ma记录每个string表示的状态是否被访问过 和 ms记录到达该状态的步骤数
map<string, int> ma, ms;
//ma中0值表示该状态没出现过, 1值表示从初态出发到达的状态, 2值表示从终态出发的状态
//ms的值表示到达每个状态所需的步数
③双向dfs:
分别从初态和终态出发,初态ma[start]=1, 终态ma[end]=2
由当前状态current到下一状态next:
Ⅰ.该状态未被访问过(即ma[next]==0)
ma[next] = ma[current]; //即由初态到达的每一状态ma的值都等于1, 由终态出发的每一状态的值都等于2
Ⅱ. 若该状态已被访问过(即ma[next]==1或者ma[next]==2)
判断ma[current]+ma[next]是否等于3,若等于三,则证明这两个是分别从初态和终态出发到达的中间状态,只要把它俩的步骤数加起来再加1,这个1是从current状态再next状态的步骤数,就是答案了;
我的代码:
#include<bits/stdc++.h>
using namespace std;
int dx[4]={0, -1, 0, 1}, dy[4]={-1, 0, 1, 0};
int a[3][3], b[3][3], sx, sy, ex, ey;
struct Node{
int arr[3][3]; //数组记录每个九宫格状态
int x, y; //x, y记录每个状态.的坐标
string str; //九宫格的字符串表示
} node[100000];
map<string, int> ma, ms;//ma中0值表示该状态没出现过, 1值表示从初态出发到达的状态, 2值表示从终态出发的状态
//ms的值表示到达每个状态所需的步数
//将数组转化为字符串函数
string toMap(int a[3][3]){
string ans="";
for(int i=0 ;i<3; i++){
for(int j=0; j<3; j++){
ans += a[i][j]+'0';
}
}
return ans;
}
//用数组模拟队列进行双向dfs
int bfs(Node nd, Node nd2){
int head = 0, tail = 0;
node[tail++] = nd;
node[tail] = nd2;
ma[nd.str] = 1;
ma[nd2.str] = 2;
while(head<=tail){
Node t = node[head];
for(int i=0; i<4; i++){
int nx = t.x + dx[i], ny = t.y + dy[i];
if(nx>=0&&nx<3&&ny>=0&&ny<3){
Node tmp;
memcpy(tmp.arr, t.arr, sizeof(t.arr));
tmp.arr[t.x][t.y] = tmp.arr[nx][ny];
tmp.arr[nx][ny] = 0;
tmp.str = toMap(tmp.arr);
if(!ma[tmp.str]){
ma[tmp.str] = ma[t.str];
ms[tmp.str] = ms[t.str] + 1;
tmp.x = nx, tmp.y = ny;
node[++tail] = tmp;
}else{
if(ma[tmp.str]+ma[t.str]==3) //两者相加等于3代表一个是由初态出发,一个是由终态出发,到达了中间状态
return ms[tmp.str]+ms[t.str]+1; //所以就等于两个状态的步骤数相加再+1
}
}
}
head++;
}
return -1;
}
int main(){
char c;
//输入初态数组
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
cin>>c;
if(c=='.'){
a[i][j] = 0;
sx = i, sy = j;
}else{
a[i][j] = c - '0';
}
}
}
//输入终态数组
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
cin>>c;
if(c=='.'){
b[i][j] = 0;
ex = i, ey = j;
}else{
b[i][j] = c - '0';
}
}
}
Node t;
memcpy(t.arr, a, sizeof(a));
t.x = sx, t.y = sy;
ms[t.str] = 0;
t.str = toMap(t.arr);
Node t2;
memcpy(t2.arr, b, sizeof(b));
t2.x = ex, t2.y = ey;
t2.str = toMap(t2.arr);
cout<<bfs(t, t2)<<endl;
return 0;
}