题意:

      讲的是一个游戏,就是在一个平面上滚动一个1*1*2的长方体的游戏,在本题里面的游戏规则是这样的:

(1)

     一开始给你箱子的状态,可能是横着也可能是竖着。

(2)

     每一次可以滚动箱子,但是每次滚动到的位置(1个或者2个)都必须不能是空的。

(3)

     有的位置只能经得起箱子一半的重量,有的能经得起真个箱子的重量,经得起一半的格子意思就是不能在当前的这个格子上吧箱子竖起来。

(4)然后问从起始状态到掉到终点给的洞里面的最小步数,掉到洞里面的时候必须是竖直掉下去的。



思路:

      比较明显可以用搜索来做,但是这个题目的关键点是如何标记状态,我的做法是对于每一个点都有五个状态,就是另一个点相对于这个点的位置,可以是东南西北,还有正上方

,标记的时候是这样的依靠五个状态,搜索的时候为了简化代码我写的是3个状态的,因为有一些等效状态,我们只要搜索其中的一个就行了,但是如果你愿意把所有的状态都写出来,那么一共是5种,每种有四个方向的走法一共是5*4种选择,这样代码量估计比较大,如果是相等状态只进一个的话可以达到3*4种选择,但是这样的话要注意就是在mark的时候的一些细节,别的没啥的就是简单广搜,姿势好点应该没啥大问题,具体细节可以看下面代码。

#include<queue>

#include<stdio.h>

#include<string.h>

using namespace std;

typedef struct

{

    int x ,y ,t ,k;

}NODE;

NODE xin ,tou;

int map[505][505] ,n ,m;

int mark[505][505][5];

int ex ,ey;

bool ok(int x ,int y ,int k)

{

    return x >= 1 && x <= n && y >= 1 && y <= m && map[x][y] && !mark[x][y][k];

}

int BFS()

{

    queue<NODE>q;

    q.push(xin);

    memset(mark ,0 ,sizeof(mark));

    mark[xin.x][xin.y][xin.k] = 1;

    NODE X1 ,X2;

    while(!q.empty())

    {

        tou = q.front();

        q.pop();

        //printf("%d %d %d %d**\n" ,tou.x ,tou.y ,tou.k ,tou.t);

        if(!tou.k && tou.x == ex && tou.y == ey)

        return tou.t;

        if(tou.k == 0)

        {

            //上

            X1.x = tou.x - 1 ,X1.y = tou.y ,X1.k = 1;

            X2.x = tou.x - 2 ,X2.y = tou.y ,X2.k = 3;

            if(ok(X1.x ,X1.y ,X1.k) && ok(X2.x ,X2.y ,X2.k))

            {

                mark[X1.x][X1.y][X1.k] = mark[X2.x][X2.y][X2.k] = 1;

                X1.t = tou.t + 1;

                q.push(X1);

            }

            //下

            X1.x = tou.x + 1 ,X1.y = tou.y ,X1.k = 3;

            X2.x = tou.x + 2 ,X2.y = tou.y ,X2.k = 1;

            if(ok(X1.x ,X1.y ,X1.k) && ok(X2.x ,X2.y ,X2.k))

            {

                mark[X1.x][X1.y][X1.k] = mark[X2.x][X2.y][X2.k] = 1;

                X2.t = tou.t + 1;

                q.push(X2);

            }

            //左

            X1.x = tou.x ,X1.y = tou.y - 1 ,X1.k = 4;

            X2.x = tou.x ,X2.y = tou.y - 2 ,X2.k = 2;

            if(ok(X1.x ,X1.y ,X1.k) && ok(X2.x ,X2.y ,X2.k))

            {

                mark[X1.x][X1.y][X1.k] = mark[X2.x][X2.y][X2.k] = 1;

                X1.t = tou.t + 1;

                q.push(X1);

            }

            //右

            X1.x = tou.x ,X1.y = tou.y + 1 ,X1.k = 2;

            X2.x = tou.x ,X2.y = tou.y + 2 ,X2.k = 4;

            if(ok(X1.x ,X1.y ,X1.k) && ok(X2.x ,X2.y ,X2.k))

            {

                mark[X1.x][X1.y][X1.k] = mark[X2.x][X2.y][X2.k] = 1;

                X2.t = tou.t + 1;

                q.push(X2);

            }

        }

        else if(tou.k == 1)

        {

            //上

            X1.x = tou.x - 2 ,X1.y = tou.y ,X1.k = 0;

            if(ok(X1.x ,X1.y ,X1.k) && map[X1.x][X1.y] == 1)

            {

                X1.t = tou.t + 1;

                mark[X1.x][X1.y][X1.k] = 1;

                q.push(X1);

            }

            //下

            X1.x = tou.x + 1 ,X1.y = tou.y ,X1.k = 0;

            if(ok(X1.x ,X1.y ,X1.k) && map[X1.x][X1.y] == 1)

            {

                X1.t = tou.t + 1;

                mark[X1.x][X1.y][X1.k] = 1;

                q.push(X1);

            }

            //左

            X1.x = tou.x ,X1.y = tou.y - 1 ,X1.k = 1;

            X2.x = tou.x - 1 ,X2.y = tou.y - 1 ,X2.k = 3;

            if(ok(X1.x ,X1.y ,X1.k) && ok(X2.x ,X2.y ,X2.k))

            {

                mark[X1.x][X1.y][X1.k] = mark[X2.x][X2.y][X2.k] = 1;

                X1.t = tou.t + 1;

                q.push(X1);

            }

            //右

            X1.x = tou.x ,X1.y = tou.y + 1 ,X1.k = 1;

            X2.x = tou.x - 1 ,X2.y = tou.y + 1 ,X2.k = 3;

            if(ok(X1.x ,X1.y ,X1.k) && ok(X2.x ,X2.y ,X2.k))

            {

                mark[X1.x][X1.y][X1.k] = mark[X2.x][X2.y][X2.k] = 1;

                X1.t = tou.t + 1;

                q.push(X1);

            }

        }

        else if(tou.k == 4)

        {

            //上

            X1.x = tou.x - 1 ,X1.y = tou.y ,X1.k = 4;

            X2.x = tou.x - 1 ,X2.y = tou.y - 1 ,X2.k = 2;

            if(ok(X1.x ,X1.y ,X1.k) && ok(X2.x ,X2.y ,X2.k))

            {

                mark[X1.x][X1.y][X1.k] = mark[X2.x][X2.y][X2.k] = 1;

                X1.t = tou.t + 1;

                q.push(X1);

            }

            //下

            X1.x = tou.x + 1 ,X1.y = tou.y ,X1.k = 4;

            X2.x = tou.x + 1 ,X2.y = tou.y - 1 ,X2.k = 2;

            if(ok(X1.x ,X1.y ,X1.k) && ok(X2.x ,X2.y ,X2.k))

            {

                mark[X1.x][X1.y][X1.k] = mark[X2.x][X2.y][X2.k] = 1;

                X1.t = tou.t + 1;

                q.push(X1);

            }

            //左

            X1.x = tou.x ,X1.y = tou.y - 2 ,X1.k = 0;

            if(ok(X1.x ,X1.y ,X1.k) && map[X1.x][X1.y] == 1)

            {

                X1.t = tou.t + 1;

                mark[X1.x][X1.y][X1.k] = 1;

                q.push(X1);

            }

            //右

            X1.x = tou.x ,X1.y = tou.y + 1 ,X1.k = 0;

            if(ok(X1.x ,X1.y ,X1.k) && map[X1.x][X1.y] == 1)

            {

                X1.t = tou.t + 1;

                mark[X1.x][X1.y][X1.k] = 1;

                q.push(X1);

            }

        }

    }

    return -1;

}

int main ()

{

    char str[505];

    int sx1 ,sx2 ,sy1 ,sy2 ,s;

    while(~scanf("%d %d" ,&n ,&m) && n + m)

    {

        s = 0;

        for(int i = 1 ;i <= n ;i ++)

        {

            scanf("%s" ,str);

            for(int j = 1 ;j <= m ;j ++)

            {

                if(str[j-1] == 'X')

                {

                    s ++;

                    if(s == 1) sx1 = i ,sy1 = j;

                    else sx2 = i ,sy2 = j;

                    map[i][j] = 1;

                }

                else if(str[j-1] == 'O')

                {

                    ex = i ,ey = j;

                    map[i][j] = 1;

                }

                else if(str[j-1] == 'E') map[i][j] = 2;

                else if(str[j-1] == '#') map[i][j] = 0;

                else map[i][j] = 1;

            }

        }

        if(s == 1) xin.x = sx1 ,xin.y = sy1 ,xin.k = 0 ,xin.t = 0;

        else

        {

            if(sx1 == sx2) xin.x = sx2 ,xin.y = sy2 ,xin.k = 4 ,xin.t = 0;

            else xin.x = xin.x = sx2 ,xin.y = sy2 ,xin.k = 1 ,xin.t = 0;

        }

        int ans = BFS();

        ans == -1 ? printf("Impossible\n") : printf("%d\n" ,ans);

    }

    return 0;

}

POJ3322滚箱子游戏(不错)的更多相关文章

  1. Unity3D游戏开发初探—4.开发一个“疯狂击箱子”游戏

    一.预备知识—对象的”生“与”死“ (1)如何在游戏脚本程序中创建对象而不是一开始就创建好对象?->使用GameObject的静态方法:CreatePrimitive() 以上一篇的博文中的“指 ...

  2. JavaScript写一个小乌龟推箱子游戏

    推箱子游戏是老游戏了, 网上有各种各样的版本, 说下推箱子游戏的简单实现,以及我找到的一些参考视频和实例: 推箱子游戏的在线DEMO : 打开 如下是效果图: 这个拖箱子游戏做了移动端的适配, 我使用 ...

  3. 用HTML5+原生js实现的推箱子游戏

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. C# 推箱子游戏&对战游戏

    推箱子游戏提纲,只有向右向上的操作,向左向下同理,后期需完善. namespace 推箱子 { class Program { static void Main(string[] args) { // ...

  5. C++学习(九)(C语言部分)之 项目 推箱子游戏

    游戏制作 推箱子 步骤分析 1.模板 2.模板分析 组成元素: 空地 墙 人 目的地 箱子 背景 3.如何操作 通过WASD键盘操作人,推着箱子,到达目的地,游戏结束,如果箱子卡在死角则游戏失败 4. ...

  6. 【CCpp程序设计2017】推箱子游戏

    我的还……支持撤销!用链表实现! 题目:推箱子小游戏(基于console) 功能要求: 将p09迷宫游戏改造为“推箱子”游戏: 在地图中增加箱子.箱子目标位置等图形: 当玩家将所有箱子归位,则显示玩家 ...

  7. JavaScript 推箱子游戏

    推箱子游戏的 逻辑非常简单,但是如果不动手的话,还是不太清楚.我在这里讲一下自己的思路. 制作推箱子,首先要有自己的设计素材.如下我也是网上找的素材 第二步,理清游戏的规则. 游戏规则: 1.小人将箱 ...

  8. three.js 制作一个三维的推箱子游戏

    今天郭先生发现大家更喜欢看我发的three.js小作品,今天我就发一个3d版本推箱子的游戏,其实webGL有很多框架,three.js并不合适做游戏引擎,但是可以尝试一些小游戏.在线案例请点击博客原文 ...

  9. 用C写一个简单的推箱子游戏(二)

    下面接着上一篇随笔<用C写一个简单的推箱子游戏(一)>来写 tuidong()函数是用来判断游戏人物前方情况的函数,是推箱子游戏中非常重要的一个函数,下面从它开始继续介绍推箱子的小程序怎么 ...

随机推荐

  1. 【秒懂音视频开发】05_Qt开发基础

    控件的基本使用 为了更好地学习Qt控件的使用,建议创建项目时先不要生成ui文件. 打开mainwindow.cpp,在MainWindow的构造函数中编写界面的初始化代码. 窗口设置 MainWind ...

  2. rsyslog日志总结

    rsyslog日志总结 一 rsyslog介绍 syslogd被rsyslog取代 将日志写入数据库 可以利用模块和插件控制输入输出 rsyslog程序管理本地和远程日志 安装软件 根据需求修改配置文 ...

  3. LNMP配置——PHP安装

    一.下载 #cd /usr/local/src //软件包都放在这里方便管理 #wget http://cn2.php.net/distributions/php-5.6.30.tar.gz 二.解压 ...

  4. Java传参:值传递 or 引用传递 ?

    刚开始学Java的时候一度以为:基本数据类型是值传递,引用类型是引用传递.新人很容易在这两个概念上面被搞糊涂,后来看了Hollis的文章才明白了Java中只有值传递. 接下来我能用简单明了的方式来说明 ...

  5. 【odoo14】第二章、管理odoo实例

    本章主要介绍肖odoo实例添加用户自定义的模块.你可以从多个路径载入模块.但是建议你将自己的模块儿放在特定的目录当中,避免与odoo的核心模块混淆. 在这一章节,中我们主要涉及以下内容: 配置插件路径 ...

  6. P3387 【模板】缩点 题解 (Tarjan)

    题目链接 P3387 [模板]缩点 解题思路 这几天搞图论,好有趣hhh,多写几篇博客. 上次学\(Tarjan\)求割点,这次缩点. 思路大概是多一个栈和染色的步骤,每次\(Tarjan\)的时候把 ...

  7. python基础学习之字符串的功能方法

    字符串:str的功能记录(该类需要记忆) .isdecimal():意思是判断是否由数字构成,仅仅可以解析"123" a='123'    d=a.isdecimal()    p ...

  8. HDU_3746 Cyclic Nacklace 【KMP的应用】

    一.题目 HDU3746 二.分析 KMP比较好解决的一个问题:如果求一个串中的循环节? 仔细回想KMP的用法,重点是next数组,相当于就是后缀和前缀的比较,那么不正是方便了我们确定循环节? 如果以 ...

  9. socket 之send和recv原理剖析

    认识TCP socket的发送缓冲区和接收缓冲区 当创建一个TCP socket对象的时候会有一个发送缓冲区和一个接收缓冲区,相当与内存中的一片空间 send原理剖析 send是不是直接把数据发送给服 ...

  10. Ubuntu20.04linux内核(5.4.0版本)编译准备与实现过程-编译过程(2)

    前面因为博客园维修,所以内核编译过程一直没有发出来,现在把整个内核过程分享出来.本随笔给出内核的编译实现过程,在编译前需要参照我前面一篇随笔: Ubuntu20.04linux内核(5.4.0版本)编 ...