HDU_5010_广搜,状压

来源:互联网 发布:昂立网络教育 编辑:程序博客网 时间:2024/05/17 05:55
/*状态如何保存呢,不懂因为题目已经说了,最多的可以走的位置不会大于32,这是不是暗示着什么呢,有点意思在仔细看一下这个地图上面的东西,会有“.(0)”、“S(1)”、“M(2)”、“P(3)”那么就是四个状态,也就是4进制,32位来表示一个四进制的3210表示十进制为3*4^3+2*4^2+1*4^1+0*4^0=228那就是4^3 = 2^6,我们记录了相对位置之后,就可以在对应位置放123了*/#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<queue>#include<map>typedef unsigned long long ull;const int maxn = 10;using namespace std;const int n = 6, m = 8;int fx[] = {-1,1,0,0};int fy[] = {0,0,-1,1};struct point//在森林中的动物{    int x,y,ani,flag;//1-s,2-m,3-p//是否还在标记中};struct node{    int size;   //动物总数    point animals[maxn];    char mp[maxn][maxn];    int flag;//早到的标志    void operator=(node a)    {        memcpy(animals, a.animals, sizeof(animals));        memcpy(mp, a.mp, sizeof(mp));        size =a.size;        flag = a.flag;    }    void Init()    {        size = 0;        for(int i = 1; i <= n; i++)        {            for(int j = 1; j <= m; j++)            {                if(mp[i][j] == 'S')                {                    animals[size].x = i;                    animals[size].y = j;                    animals[size].flag = 0;                    animals[size++].ani = 1;                }                if(mp[i][j] == 'M')                {                    animals[size].x = i;                    animals[size].y = j;                    animals[size].flag = 0;                    animals[size++].ani = 2;                }                if(mp[i][j] == 'P')                {                    animals[size].x = i;                    animals[size].y = j;                    animals[size].flag = 0;                    animals[size++].ani = 3;                }            }        }    }};char mp[maxn][maxn];//初始地图int bp[maxn][maxn]; //记录空位的编码int tot;            //状态映射ull bit[70];        //进制转换map<ull, int>vis;queue<node>que;bool chare(int x,int y)//判断是否越界{    if(x<1||y<1||x>n||y>m)return false;    return true;}void Init()//记录空格对应位{    int tt = 0;    for(int i = 1; i <= n; i++)    {        for(int j = 1; j <= m; j++)        {            if(mp[i][j] == '#' || mp[i][j] == 'N')                continue;            bp[i][j] = tt++;        }    }}ull Getnum(char mp[maxn][maxn])//对应状态{    ull ret = 0;     for(int i = 1; i <= n; i++)    {        for(int j = 1; j <= m; j++)        {            if(mp[i][j] == 'S')            {                ret += 1*bit[bp[i][j]<<1];            }            else if(mp[i][j] == 'M')            {                ret += 2*bit[bp[i][j]<<1];            }            else if(mp[i][j] == 'P')            {                ret += 3*bit[bp[i][j]<<1];            }        }    }    return ret;}void move(int f,int ani,node &he){    int xi = he.animals[ani].x;    int yi = he.animals[ani].y;    he.mp[xi][yi]='.';    if(he.animals[ani].ani == 1)//人在走    {        xi += fx[f];        yi += fy[f];//走了一步,人的那一步,只要不是树,和老鼠就可以走,因为碰见猪就被吃了,碰见海螺就结束游戏了,所以不会跟他们同格        while(chare(xi,yi)&&he.mp[xi][yi]!='#'&&he.mp[xi][yi]!='M'&&he.mp[xi][yi]!='S')//这一步是有效的        {            //先检查是否有猪            if(he.mp[xi+1][yi]=='P'||he.mp[xi-1][yi]=='P'||he.mp[xi][yi+1]=='P'||he.mp[xi][yi-1]=='P')                return;            //检查是有嗨喽            if(he.mp[xi+1][yi]=='N'||he.mp[xi-1][yi]=='N'||he.mp[xi][yi+1]=='N'||he.mp[xi][yi-1]=='N')            {                he.flag = 1;                return;            }            xi += fx[f];            yi += fy[f];        }        xi -= fx[f];        yi -= fy[f];        he.mp[xi][yi] = 'S';        he.animals[ani].x=xi;        he.animals[ani].y=yi;        ull stt = Getnum(he.mp);        if(vis.find(stt) == vis.end())        {            vis[stt] = 1;            que.push(he);        }    }    if(he.animals[ani].ani==2)//老鼠在走    {        xi += fx[f];        yi += fy[f];//走了一步,人的那一步,只要不是树,和老鼠就可以走,因为碰见猪就被吃了,碰见海螺就结束游戏了,所以不会跟他们同格        while(chare(xi,yi)&&he.mp[xi][yi]!='#'&&he.mp[xi][yi]!='S'&&he.mp[xi][yi]!='M')//这一步是有效的        {            //先检查是否有猪            if(he.mp[xi+1][yi]=='P'||he.mp[xi-1][yi]=='P'||he.mp[xi][yi+1]=='P'||he.mp[xi][yi-1]=='P')            {                he.animals[ani].flag = 1;//被吃掉了                ull stt = Getnum(he.mp);                if(vis.find(stt) == vis.end())                {                    vis[stt] = 1;                    que.push(he);                }                return;            }            //检查是有嗨喽            if(he.mp[xi+1][yi]=='N'||he.mp[xi-1][yi]=='N'||he.mp[xi][yi+1]=='N'||he.mp[xi][yi-1]=='N')            {                return;            }            xi += fx[f];            yi += fy[f];        }        xi -= fx[f];        yi -= fy[f];        he.mp[xi][yi] = 'M';        he.animals[ani].x=xi;        he.animals[ani].y=yi;        ull stt = Getnum(he.mp);        if(vis.find(stt) == vis.end())        {            vis[stt] = 1;            que.push(he);        }    }    if(he.animals[ani].ani==3)//猪就比较有搞头了,    {        int eat = 0;        xi += fx[f];        yi += fy[f];        while(chare(xi,yi)&&he.mp[xi][yi]!='#'&&he.mp[xi][yi]!='P')        {            for(int j = 0; j < 4; j++)//扫描当前点的四周            {                if(he.mp[xi+fx[j]][yi+fy[j]] =='S'||he.mp[xi+fx[j]][yi+fy[j]]=='M')//有人、老鼠                {                    eat = 1;                    he.mp[xi+fx[j]][yi+fy[j]] = '.';                    for(int i = 0; i < he.size; i++)                    {                        if(he.animals[i].x == xi+fx[j] && he.animals[i].y == yi+fy[j])                        {                            he.animals[i].flag = 1;                            break;                        }                    }                }                if(he.mp[xi+fx[j]][yi+fy[j]] =='N')return;            }            if(eat)            {                he.mp[xi][yi] = 'P';                he.animals[ani].x=xi;                he.animals[ani].y=yi;                ull stt = Getnum(he.mp);                if(vis.find(stt) == vis.end())                {                    vis[stt] = 1;                    que.push(he);                }                return;            }            xi += fx[f];            yi += fy[f];        }        xi -= fx[f];        yi -= fy[f];        he.mp[xi][yi] = 'P';        he.animals[ani].x=xi;        he.animals[ani].y=yi;        ull stt = Getnum(he.mp);        if(vis.find(stt) == vis.end())        {            vis[stt] = 1;            que.push(he);        }    }}int bfs(){    ull p1,q1;    node p,q;    memcpy(p.mp, mp,sizeof(p.mp));    p.Init();    p.flag=0;    p1 = Getnum(p.mp);    vis.clear();    vis.insert(pair<ull,int>(p1,1));    while (!que.empty())que.pop();    que.push(p);    int stap = 0;    while(!que.empty())    {        stap++;        int size = que.size();        while(size--)        {            p = que.front();            que.pop();            for(int i = 0; i < p.size; i++)//对里面的动物进行移动            {                if(p.animals[i].flag)continue;                for(int j = 0; j < 4; j++)                {                    q = p;                    move(j,i,q);//i去跑                    if(q.flag)return stap;                }            }        }    }    return -1;}int main(){       //freopen("in.txt","r",stdin);    bit[0] = 1;    for(int i = 1; i <= 64; i++)        bit[i] = bit[i-1]*2;    while(scanf("%s",mp[1]+1)!=EOF)    {        for(int i = 2; i <= n; i++)            scanf("%s",mp[i]+1);        Init();        printf("%d\n",bfs());    }    return 0;}
0 0
原创粉丝点击