#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <vector>
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define zero(x) (fabs(x)<eps)
#define pi acos(-1.0)
#define f1 first
#define f2 second
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define initial 1,n,1
const int inf=0x3f3f3f3f;
const long long INF=1LL<<50;
using namespace std;
typedef long long LL;
typedef pair <int, int> PII;
template<typename X> inline bool minimize(X&p,X q){if(p<=q)return 0;p=q;return 1;}
template<typename X> inline bool maximize(X&p,X q){if(p>=q)return 0;p=q;return 1;}
const int dx[4]={0,0,1,-1};
const int dy[4]={1,-1,0,0};
const int n=6,m=8,T1=8,T2=10;
int an[7],wei[7],tmp[7],ttmp[7];
int x[35],y[35],stop[35],v[35][35];
int map[T1][T2],id[T1][T2];
char s[T1][T2];
queue <int > q;
int o,tx,ty,sx,sy,ss,tt;
const int HASH=1000003;
const int STATE=1000000;//提交证明状态数未超过100W
int head[HASH],next[STATE],size;
int state[STATE];
int f[STATE];
void init()
{
size=0;
memset(head,-1,sizeof(head));
}
bool push(int st,int ans)
{
int i;
int h=st%HASH;
for(i=head[h];i!=-1;i=next[i])
if(state[i]==st)
{
if (ans<f[i]){f[i]=ans;//printf("##:%d %d ",st,ans);
return 1;}
return 0;
}
state[size]=st;
f[size]=ans;
next[size]=head[h];
head[h]=size++;
return 1;
}
int push_get(int st)
{
int i;
int h=st%HASH;
for(i=head[h];i!=-1;i=next[i])
if(state[i]==st)return f[i];
}
/*************************/
int code(int *tmp)
{ int re=0;
for (int i=an[0];i>=1;i--)
re=re*o+tmp[i];
return re;
}
void decode(int *tmp,int sta)
{
for (int i=1;i<=an[0];i++)
{
tmp[i]=sta%o;
sta/=o;
}
}
/**********************/
void get(int stop[],int tmp[],int k,int fa)
{
for (int ii=0;ii<o;ii++)
stop[ii]=0;
stop[tt]=1;
if (an[k]==2)
{
for (int j=1;j<=an[0];j++)if (tmp[j]!=o-1)
{ int nx=x[tmp[j]],ny=y[tmp[j]],nnx,nny;
stop[id[nx][ny]]=1;//
if (an[j]!=2)
for (int dir=0;dir<4;dir++)
{ nnx=nx+dx[dir];
nny=ny+dy[dir];
if (nnx<0||nnx>=n||nny<0||nny>=m)continue;
if (map[nnx][nny]==2)continue;
if (stop[id[nnx][nny]]==0)stop[id[nnx][nny]]=2;
}
}
}
else{
for (int j=1;j<=an[0];j++)if (tmp[j]!=o-1)
{ int nx=x[tmp[j]],ny=y[tmp[j]],nnx,nny;
stop[id[nx][ny]]=1;//
if (an[j]==2)
for (int dir=0;dir<4;dir++)
{ nnx=nx+dx[dir];
nny=ny+dy[dir];
if (nnx<0||nnx>=n||nny<0||nny>=m)continue;
if (map[nnx][nny]==2)continue;
if (stop[id[nnx][nny]]==0)stop[id[nnx][nny]]=2;
}
}
}
}
/*************************/
void bfs()
{
while (!q.empty()) q.pop();init();
//----------------------
int rr,sta,newsta,step,moveid,nnx,nny;
rr=code(wei);
push(rr,0);
q.push(rr);
int anss=0;
while (!q.empty())
{
sta=q.front(); q.pop();
decode(tmp,sta);
step=push_get(sta);
step++;anss++;
for (int i=1;i<=an[0];i++)if (tmp[i]!=o-1)
{ get(stop,tmp,i,1);
moveid=tmp[i];
for (int dir=0;dir<4;dir++)
{
nnx=x[tmp[i]]+dx[dir],nny=y[tmp[i]]+dy[dir];
while (1)
{ if (nnx<0||nnx>=n||nny<0||nny>=m)break;
if (map[nnx][nny]==2)break;
if (stop[id[nnx][nny]])break;
nnx+=dx[dir],nny+=dy[dir];
}
if (nnx<0||nnx>=n||nny<0||nny>=m){nnx-=dx[dir];nny-=dy[dir];}
else if (map[nnx][nny]==2){nnx-=dx[dir];nny-=dy[dir];}
else if (stop[id[nnx][nny]]!=2){nnx-=dx[dir];nny-=dy[dir];}
if (id[nnx][nny]==moveid)continue;
for (int ii=1;ii<=an[0];ii++)ttmp[ii]=tmp[ii];
ttmp[i]=id[nnx][nny];
//kaichi
if (an[i]==2&&ttmp[i]!=o-1)
{
for (int ii=1;ii<=an[0];ii++)if (tmp[ii]!=o-1)if (an[ii]!=2)
if (v[tmp[ii]][ttmp[i]]) ttmp[ii]=o-1;
}
if (an[i]!=2&&ttmp[i]!=o-1)
{
for (int ii=1;ii<=an[0];ii++)if (tmp[ii]!=o-1)if (an[ii]==2)
if (v[tmp[ii]][ttmp[i]]) {ttmp[i]=o-1;}
}
if (an[i]!=3&&ttmp[i]!=o-1)
{
if (v[ttmp[i]][tt]) continue;
}
if (an[i]==3&&ttmp[i]==o-1) continue;
//jieshu
if (v[ttmp[i]][tt])
{
printf("%d\n",step);
return;
}
newsta=code(ttmp);
if (push(newsta,step)) {
q.push(newsta);
//printf("sta:%d i:%d dir:%d newsta:%d (%d %d %d %d %d)->(%d %d %d %d %d) \n",sta,i,dir,newsta,tmp[1],tmp[2],tmp[3],tmp[4],tmp[5],ttmp[1],ttmp[2],ttmp[3],ttmp[4],ttmp[5]);
}
}
}
//break;
}
}
void doit()
{
for (int i=1;i<n;i++)
cin>>s[i];
o=0;an[0]=0;
memset(id,255,sizeof(id));
for (int i=0;i<n;i++)
for (int j=0;j<m;j++)
{
if (s[i][j]=='.') map[i][j]=1;
if (s[i][j]=='#') map[i][j]=2;
if (s[i][j]=='S') {map[i][j]=3; sx=i;sy=j;}
if (s[i][j]=='M') {map[i][j]=4;}
if (s[i][j]=='P') {map[i][j]=5;}
if (s[i][j]=='N') {map[i][j]=6; tx=i;ty=j;}
if (map[i][j]!=2)
{
x[o]=i;
y[o]=j;
id[i][j]=o;
o++;
}
}
for (int i=0;i<n;i++)
for (int j=0;j<m;j++)
{
if (s[i][j]=='M') {++an[0];an[an[0]]=1;wei[an[0]]=id[i][j];}
if (s[i][j]=='P') {++an[0];an[an[0]]=2;wei[an[0]]=id[i][j];}
}
ss=id[sx][sy];
tt=id[tx][ty];
++an[0];
an[an[0]]=3;wei[an[0]]=id[sx][sy];
memset(v,0,sizeof(v));
for (int i=0;i<o;i++)
for (int j=i+1;j<o;j++)
if ((abs(x[i]-x[j])==1&&abs(y[i]-y[j])==0)||(abs(x[i]-x[j])==0&&abs(y[i]-y[j])==1))
v[i][j]=v[j][i]=1;
o++;
bfs();
}
int main()
{ //freopen("in.txt","r",stdin);
int id=0;
while (cin>>s[0]) {doit();}
}
hdu 5010 大搜索
最新推荐文章于 2020-01-28 22:06:03 发布