题目:http://acm.hdu.edu.cn/showproblem.php?pid=3095
很好的题。。用BFS一直爆内存,想了各种优化都没能AC掉。。后面改为双向BFS。。才成功AC!
最近一直在练习搜索题目,发现打搜索很能提高驾驭代码的能力。如果搜索都能很快打对。那么打其他的应该也不难。搜索打多了,很多2B的逻辑错误就不容易犯了。。
代码依旧写得很烂。那是因为总是对这个代码缝缝补补。。
下面是AC代码:
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<map>
using namespace std;
int maze[10][10];
int end_maze[10][10];
int flag,ans;
struct node
{
int x[2],y[2];
int maze[6][6];
int step;
} s_pos,e_pos;
int dir[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};
string end;
bool cheack(int x,int y)
{
return x>=1&&x<=5&&y>=1&&y<=5;
return false;
}
void bfs()
{
queue<node > q[2];
map<string ,int > vis[2];
string temp="";
for(int i=1; i<=5; i++) for(int j=1; j<=5; j++)
if(s_pos.maze[i][j]!=-1)
{
if(s_pos.maze[i][j]<10)
temp+=(s_pos.maze[i][j]+'0');
else
{
temp+='a'+s_pos.maze[i][j]-10;
}
}
if(temp==end)
{
flag=1;
ans=0;
return ;
}
q[0].push(s_pos);
q[1].push(e_pos);
vis[0][temp]=1;
vis[1][end]=1;
while(!q[0].empty()||!q[1].empty())
{
for(int index=0; index<2; index++)
{
node now = q[index].front();
q[index].pop();
for(int i=0; i<2; i++)
{
for(int j=0; j<4; j++)
{
node next = now;
next.step+=1;
int x=next.x[i],y=next.y[i]; //0的位置
int nx=x+dir[j][0],ny=y+dir[j][1]; //下一步O的位置
if(now.maze[x][y]==0&&now.maze[nx][ny]==0) continue ;
if(cheack(nx,ny)&&maze[nx][ny]!=-1)
{
next.maze[x][y]=now.maze[nx][ny];
next.maze[nx][ny]=0;
next.x[i]=nx;
next.y[i]=ny;
temp="";
for(int l=1; l<=5; l++) for(int k=1; k<=5; k++)
if(next.maze[l][k]!=-1)
{
if(next.maze[l][k]<10)
temp+=(next.maze[l][k]+'0');
else
{
temp+='a'+next.maze[l][k]-10;
}
}
if(vis[1-index][temp])
{
flag=1;
ans=next.step+vis[1-index][temp]-1;
return ;
}
if(next.step>11) return ;
if(!vis[index][temp])
{
vis[index][temp]=next.step+1;
q[index].push(next);
}
}
}
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
end="";
for(int i=0; i<=9; i++) end+=(i+'0');
end+='a';
end+='b';
end+='0';
for(int i=1; i<=5; i++) for(int j=1; j<=5; j++) end_maze[i][j]=-1;
end_maze[1][3]=end_maze[5][3]=0;
int k=1;
for(int i=2; i<=4; i++) end_maze[2][i]=k++;
for(int i=1; i<=5; i++) end_maze[3][i]=k++;
for(int i=2; i<=4; i++) end_maze[4][i]=k++;
while(t--)
{
for(int i=1; i<=5; i++) for(int j=1; j<=5; j++) maze[i][j]=-1;
maze[1][3]=maze[5][3]=1;
for(int i=2; i<=4; i++) maze[2][i]=maze[4][i]=1;
for(int i=1; i<=5; i++) maze[3][i]=1;
int len=0;
for(int i=1; i<=5; i++)
for(int j=1; j<=5; j++)
{
if(maze[i][j]==-1) continue ;
scanf("%d",&maze[i][j]);
if(maze[i][j]==0)
{
s_pos.x[len]=i;
s_pos.y[len]=j;
len++;
}
}
s_pos.step=0;
s_pos.step=0;
e_pos.x[0]=1;
e_pos.y[0]=3;
e_pos.x[1]=5;
e_pos.y[1]=3;
for(int i=1; i<=5; i++) for(int j=1; j<=5; j++)
{
s_pos.maze[i][j]=maze[i][j];
e_pos.maze[i][j]=end_maze[i][j];
}
flag=0;
bfs();
if(flag&&ans<=20) printf("%d\n",ans);
else printf("No solution!\n");
}
return 0;
}