bfs暴搜,重点在于记录状态与判重
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
struct Point{
int x[4],y[4],step;
Point(int *a,int *b,int n){
step=n;
for(int i=0;i<4;i++)
x[i]=a[i],y[i]=b[i];
}
};
int n,m,dx[]={-1,1,0,0},dy[]={0,0,-1,1};
int a[10],b[10];
char map[10][10];
bool vis[8][8][8][8][8][8][8][8],solve[8][8][8][8][8][8];
queue<Point> q;
bool in(int x,int y){
return x<n&&x>=0&&y<m&&y>=0&&map[x][y]!='#';
}
bool inter(int x,int y,Point p){
for(int i=1;i<4;i++)
if(x==p.x[i]&&y==p.y[i])
return true;
return false;
}
void set(Point p){
for(int i=1;i<4;i++)
for(int j=1;j<4;j++)
for(int k=1;k<4;k++)
vis[p.x[0]][p.y[0]][p.x[i]][p.y[i]][p.x[j]][p.y[j]][p.x[k]][p.y[k]]=true;
}
int bfs(){
Point p(a,b,0);
while(!q.empty()) q.pop();
q.push(p);
memset(vis,false,sizeof(vis));
while(!q.empty()){
p=q.front();q.pop();
if(solve[p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]])
return p.step;
int x=p.x[0],y=p.y[0];
for(int i=0;i<4;i++){
int nx=x+dx[i],ny=y+dy[i];
if(!in(nx,ny)) continue;
int j;
for(j=1;j<4;j++)
if(nx==p.x[j]&&ny==p.y[j]){
if(in(p.x[j]+dx[i],p.y[j]+dy[i])&&!inter(p.x[j]+dx[i],p.y[j]+dy[i],p)){
Point tp(p.x,p.y,p.step+1);
tp.x[j]=p.x[j]+dx[i];
tp.y[j]=p.y[j]+dy[i];
tp.x[0]=nx;tp.y[0]=ny;
if(vis[tp.x[0]][tp.y[0]][tp.x[1]][tp.y[1]][tp.x[2]][tp.y[2]][tp.x[3]][tp.y[3]])
break;
set(tp);
q.push(tp);
break;
}
break;
}
if(j==4){
Point tp(p.x,p.y,p.step+1);
tp.x[0]=nx;tp.y[0]=ny;
if(vis[tp.x[0]][tp.y[0]][tp.x[1]][tp.y[1]][tp.x[2]][tp.y[2]][tp.x[3]][tp.y[3]])
continue;
set(tp);
q.push(tp);
}
}
}
return -1;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
while(cin>>n>>m){
int cnt1=1,cnt2=1,ax[10],bx[10];
memset(solve,false,sizeof(solve));
for(int i=0;i<n;i++){
scanf("%s",map[i]);
for(int j=0;j<m;j++)
if(map[i][j]=='*')
a[cnt1]=i,b[cnt1++]=j;
else if(map[i][j]=='@')
ax[cnt2]=i,bx[cnt2++]=j;
}
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(map[i][j]=='X'){
a[0]=i,b[0]=j;
break;
}
for(int i=1;i<4;i++)
for(int j=1;j<4;j++)
for(int k=1;k<4;k++)
solve[ax[i]][bx[i]][ax[j]][bx[j]][ax[k]][bx[k]]=true;
cout<<bfs()<<endl;
}
return 0;
}