HOLEDOX MOVING (POJ1324)

来源:互联网 发布:第九单片机论坛 编辑:程序博客网 时间:2024/06/06 09:02

在这里我们将蛇的状态描述为如下三元组(x,y,sta),其中 (x,y)是蛇头的坐标,state 记录的是身体的状态,由于身体最长为七段,每一段相对于前一段只有上下左右四种状态,仅需要两位表示,则身体所有块的状态最多需要 7×2=14 位二进制数表示,则我们可以构建矩阵vis[x][y][sta] 来保存访问过的状态,以避免重复访问相同的状态,后面的工作就是传统的广搜过程了;
代码很容易看得懂

#include <iostream>#include <algorithm>#include <vector>#include <list>#include <map>#include <cstdio>#include <cstring>#include <queue>`这里写代码片`using namespace std;int vis[21][21][17000];int fac[15];int g[21][21];int **start;int n,m,len,k;int dir[4][2]= {{0,1},{1,0},{0,-1},{-1,0}};struct node{    int step;    int p[8][2];    node(int sst,int **pp,int s):step(sst)    {        for(int i=0; i<len; i++)            for(int j=0; j<2; j++)            {                p[i][j]=pp[i][j];            }        sta=s;    }    int sta;};int getnum(int **p){    int sta=0;    for(int i=1; i<len; i++)    {        if(p[i-1][0]+1==p[i][0]&&p[i-1][1]==p[i][1])        {            sta+=0;        }        else if(p[i-1][0]==p[i][0]&&p[i-1][1]+1==p[i][1])        {            sta+=(1*fac[(i-1)*2]+0*fac[(i-1)*2+1]);        }        else if(p[i-1][0]-1==p[i][0]&&p[i-1][1]==p[i][1])        {            sta+=(1*fac[(i-1)*2]+1*fac[(i-1)*2+1]);        }        else if(p[i-1][0]==p[i][0]&&p[i-1][1]-1==p[i][1])        {            sta+=(0*fac[(i-1)*2]+1*fac[(i-1)*2+1]);        }    }    return sta;}void init(){    fac[0]=1;    for(int i=1; i<=14; i++)    {        fac[i]=fac[i-1]*2;    }}int bfs(){    queue<node *> q;    bool flag=true;    for(int i=0; i<len; i++)    {        if(start[i][0]>n||start[i][0]<1||start[i][1]>m||start[i][1]<1||g[start[i][0]][start[i][1]]==1)        {            flag=false;            break;        }    }    if(!flag)        return -1;    if(start[0][0]==1&&start[0][1]==1)        return 0;    q.push(new node(0,start,getnum(start)));    vis[start[0][0]][start[0][1]][getnum(start)]=1;    int time=-1;    while(!q.empty())    {        node *cur=q.front();        q.pop();        if(cur->p[0][0]==1&&cur->p[0][1]==1)        {            time=cur->step;            break;        }        for(int i=0; i<4; i++)        {            int **tempp=new int *[len];            for(int j=0; j<len; j++)                tempp[j]=new int[2];            tempp[0][0]=cur->p[0][0]+dir[i][0];            tempp[0][1]=cur->p[0][1]+dir[i][1];            bool flag1=true;            for(int j=1; j<len; j++)            {                if(tempp[0][0]==cur->p[j][0]&&tempp[0][1]==cur->p[j][1])                {                    flag1=false;                    break;                }            }            if(!flag1)                continue;            for(int j=1; j<len; j++)            {                tempp[j][0]=cur->p[j-1][0];                tempp[j][1]=cur->p[j-1][1];            }            for(int j=0; j<len; j++)            {                if(tempp[j][0]>n||tempp[j][0]<1||tempp[j][1]>m||tempp[j][1]<1||g[tempp[j][0]][tempp[j][1]])                    continue;            }            int sta1=getnum(tempp);            if(!vis[tempp[0][0]][tempp[0][1]][sta1])            {                q.push(new node(cur->step+1,tempp,sta1));                vis[tempp[0][0]][tempp[0][1]][sta1]=1;            }        }    }    return time;}int main(){    start=new int*[8];    for(int i=0; i<8; i++)        start[i]=new int[2];    init();    while(scanf("%d%d%d",&n,&m,&len)&&(len+m+n)!=0)    {        memset(vis,0,sizeof(vis));        memset(g,0,sizeof(g));        for(int i=0; i<len; i++)            scanf("%d%d",&start[i][0],&start[i][1]);        scanf("%d",&k);        for(int i=0; i<k; i++)        {            int x,y;            scanf("%d%d",&x,&y);            g[x][y]=1;        }        int time=bfs();        cout<<time<<endl;    }}
0 0
原创粉丝点击