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

本文介绍了一款方块游戏的实现方法,重点讲解了如何使用三维数组进行状态记录及辅助数组来简化移动操作,同时提供了两种不同版本的C++代码实现:单一搜索和双向搜索算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

方块的状态有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;
}


资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值