hdu 5010 大搜索

来源:互联网 发布:js 声明json对象 编辑:程序博客网 时间:2024/05/04 05:32
#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,1const 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();}}

0 0