hdu 5010 大搜索

#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();}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值