poj 3322 Bloxorz I (bfs+辅助数组减代码量)

很好玩的一个游戏,建议大家做完了去玩一玩~。

方块的状态有3种情况,竖着,横躺着,竖躺着,所以可以用一个标记变量表示。

对于判重,可以开一个三维的数组来判断。

麻烦的地方在于移动,如果直接模拟的话,将会产生很大的代码量。250~300行左右……

可以开几个辅助数组,直接判断上下左右时相应的坐标变化。

写辅助数组时最好头脑清醒,写错了某个的话,debug都很困难。。。(可以注意上下的对称性)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
char map[505][505];
int endx,endy;
struct node
{
   int dis;
   int flag;        //0=竖着,1=横躺着,2=竖躺着
   int x1;
   int y1;
   int x2;
   int y2;
}start;
node q[1000000];
bool vis[505][505][3];
int dx1[3][4]={{-2,1,0,0},{-1,1,0,0},{-1,2,0,0}};
int dy1[3][4]={{0,0,-2,1},{0,0,-1,2},{0,0,-1,1}};
int ddx[4]={-1,1,0,0};
int ddy[4]={0,0,-1,1};
int dx2[3][4]={{-1,2,0,0},{-1,1,0,0},{-2,1,0,0}};
int dy2[3][4]={{0,0,-1,2},{0,0,-2,1},{0,0,-1,1}};
int c[3][4]={{2,2,1,1},{1,1,0,0},{0,0,2,2}};
int n,m;
bool f(int x,int y)
{
    return x>=0&&x<n&&y>=0&&y<m;
}
bool isok(node &t)
{
    if(!f(t.x1,t.y1)||!f(t.x2,t.y2)) return false;
    if(t.flag==0&&map[t.x1][t.y1]=='E') return false;
    if(map[t.x1][t.y1]=='#'||map[t.x2][t.y2]=='#') return false;
    return true;
}

void creat()
{
   for(int i=0;i<n;i++)
   for(int j=0;j<m;j++)
   {
       if(map[i][j]=='O')
       {
           endx=i;endy=j;
       }
       else if(map[i][j]=='X')
       {
           start.x2=start.x1=i;start.y2=start.y1=j;
           int rx=i+ddx[3],ry=j+ddy[3];
           int dx=i+ddx[1],dy=j+ddy[1];
           if(f(rx,ry)&&map[rx][ry]=='X')
           {
               start.flag=1;
               start.x2=rx;start.y2=ry;
               map[i][j]=map[rx][ry]='.';
           }
           else if(f(dx,dy)&&map[dx][dy]=='X')
           {
               start.flag=2;
               start.x2=dx;start.y2=dy;
               map[i][j]=map[dx][dy]='.';
           }
           else
           {
               start.flag=0;
               map[i][j]='.';
           }
       }
   }
   start.dis=0;
}
bool expend(node &t,int d)
{
    t.x1+=dx1[t.flag][d];
    t.y1+=dy1[t.flag][d];
    t.x2+=dx2[t.flag][d];
    t.y2+=dy2[t.flag][d];
    t.dis++;
    t.flag=c[t.flag][d];
    if(!isok(t)) return false;
    if(!vis[t.x1][t.y1][t.flag])
    {

        vis[t.x1][t.y1][t.flag]=1;
        return true;
    }
    return false;
}
void bfs()
{
    int rear=0,front=0;
    q[rear++]=start;
    node f,r;
    while(front<rear)
    {
        f=q[front];
        for(int d=0;d<4;d++)
        {
            r=f;
            if(expend(r,d))
            {
                q[rear++]=r;
                if(r.x1==endx&&r.y1==endy&&r.flag==0)
                {
                    printf("%d\n",r.dis);
                    return;
                }
            }
        }
        front++;
    }
    printf("Impossible\n");
}
int main()
{

    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(!n&&!m) break;
        for(int i=0;i<n;i++)
        {
            scanf("%s",map[i]);
        }
        memset(vis,0,sizeof(vis));
        creat();
        bfs();
    }
    return 0;
}


900多ms很不满意,直接把原代码改成了双搜,竟然还是800多ms。。。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
char map[505][505];
int endx,endy;
struct node
{
   int dis;
   int flag;        //0=竖着,1=横躺着,2=竖躺着
   int x1;
   int y1;
   int x2;
   int y2;
}start,end;
node q1[1000000];
node q2[1000000];
int vis[505][505][3];
int vis2[505][505][3];
int dx1[3][4]={{-2,1,0,0},{-1,1,0,0},{-1,2,0,0}};
int dy1[3][4]={{0,0,-2,1},{0,0,-1,2},{0,0,-1,1}};
int ddx[4]={-1,1,0,0};
int ddy[4]={0,0,-1,1};
int dx2[3][4]={{-1,2,0,0},{-1,1,0,0},{-2,1,0,0}};
int dy2[3][4]={{0,0,-1,2},{0,0,-2,1},{0,0,-1,1}};
int c[3][4]={{2,2,1,1},{1,1,0,0},{0,0,2,2}};
int n,m;
bool f(int x,int y)
{
    return x>=0&&x<n&&y>=0&&y<m;
}
bool isok(node &t)
{
    if(!f(t.x1,t.y1)||!f(t.x2,t.y2)) return false;
    if(t.flag==0&&map[t.x1][t.y1]=='E') return false;
    if(map[t.x1][t.y1]=='#'||map[t.x2][t.y2]=='#') return false;
    return true;
}

void creat()
{
   for(int i=0;i<n;i++)
   for(int j=0;j<m;j++)
   {
       if(map[i][j]=='O')
       {
           endx=i;endy=j;
           end.x1=end.x2=i;
           end.y1=end.y2=j;
           end.flag=0;
           end.dis=0;
       }
       else if(map[i][j]=='X')
       {
           start.x2=start.x1=i;start.y2=start.y1=j;
           int rx=i+ddx[3],ry=j+ddy[3];
           int dx=i+ddx[1],dy=j+ddy[1];
           if(f(rx,ry)&&map[rx][ry]=='X')
           {
               start.flag=1;
               start.x2=rx;start.y2=ry;
               map[i][j]=map[rx][ry]='.';
           }
           else if(f(dx,dy)&&map[dx][dy]=='X')
           {
               start.flag=2;
               start.x2=dx;start.y2=dy;
               map[i][j]=map[dx][dy]='.';
           }
           else
           {
               start.flag=0;
               map[i][j]='.';
           }
       }
   }
   start.dis=0;
}
bool expend(node &t,int d)
{
    t.x1+=dx1[t.flag][d];
    t.y1+=dy1[t.flag][d];
    t.x2+=dx2[t.flag][d];
    t.y2+=dy2[t.flag][d];
    t.dis++;
    t.flag=c[t.flag][d];
    if(!isok(t)) return false;
    return true;
}
void bfs()
{
    int rear1=0,front1=0;
    q1[rear1++]=start;
    int rear2=0,front2=0;
    q2[rear2++]=end;
    node f1,r1,f2,r2;
    int k1=1,kk1=0,k2=1,kk2=0;
    while(front1<rear1&&front2<rear2)
    {
        while(k1--){
        f1=q1[front1];front1++;
        for(int d=0;d<4;d++)
        {
            r1=f1;
            if(expend(r1,d))
            {
                if(vis2[r1.x1][r1.y1][r1.flag])
                {
                    if(vis2[r1.x1][r1.y1][r1.flag]==-1)
                    vis2[r1.x1][r1.y1][r1.flag]=0;
                    printf("%d\n",r1.dis+vis2[r1.x1][r1.y1][r1.flag]);
                    return;
                }
                if(!vis[r1.x1][r1.y1][r1.flag])
                {
                    vis[r1.x1][r1.y1][r1.flag]=r1.dis;
                    q1[rear1++]=r1;
                    kk1++;
                }
            }
        }
        }
        k1=kk1;kk1=0;
        while(k2--)
        {
            f2=q2[front2];front2++;
        for(int d=0;d<4;d++)
        {
            r2=f2;
            if(expend(r2,d))
            {
                if(vis[r2.x1][r2.y1][r2.flag])
                {
                    if(vis[r2.x1][r2.y1][r2.flag]==-1)
                    vis[r2.x1][r2.y1][r2.flag]=0;
                    printf("%d\n",r2.dis+vis[r2.x1][r2.y1][r2.flag]);
                    return;
                }
                if(!vis2[r2.x1][r2.y1][r2.flag])
                {
                    vis2[r2.x1][r2.y1][r2.flag]=r2.dis;
                    q2[rear2++]=r2;
                    kk2++;
                }
            }
        }
        }
        k2=kk2;
        kk2=0;
    }
    printf("Impossible\n");
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(!n&&!m) break;
        for(int i=0;i<n;i++)
        {
            scanf("%s",map[i]);
        }
        memset(vis,0,sizeof(vis));
        memset(vis2,0,sizeof(vis2));
        creat();
        vis2[end.x1][end.y1][end.flag]=-1;
        vis[start.x1][start.y1][start.flag]=-1;
        bfs();
    }
    return 0;
}


你可能感兴趣的:(poj 3322 Bloxorz I (bfs+辅助数组减代码量))