问题描述

推箱子是一款经典的小游戏。游戏要求玩家将若干个箱子推到指定的位置,并以箱子移动次数最少作为目标。 现在,我们只需要考虑一个简化的版本——只有一个箱子。对于一张给定的地图,你需要判断是否可以将箱子推到目标位置,如果可以,你还需要求出箱子最少的移动次数。

输入格式

第一行有两个用单个空格分隔的正整数n,m(n,m<=100),表示输入一张n∗m的地图。 接下来n行,每行m个字母,字母分别是S, M, P, K, w,意义如下: S – 表示地图中的墙 M – 表示玩家的初始位置 P – 表示箱子的初始位置 K- 表示箱子的目标位置 w – 表示地图中的空格 M, P 和 K 在文件中只出现一次

输出格式

如果箱子不能移动到目的位置,则输出NO。

如果箱子能移动到目的位置,则输出最小的移动次数。

样例输入

10 12
SSSSSSSSSSSS
SwwwwwwwSSSS
SwSSSSwwSSSS
SwSSSSwwSKSS
SwSSSSwwSwSS
SwwwwwPwwwww
SSSSSSSwSwSw
SSSSSSMwSwww
SSSSSSSSSSSS
SSSSSSSSSSSS

样例输出

7

数据范围

对于10%的数据: n=1或m=1

另10%的数据: n=5,m=100或n=100,m=5

对于30%的数据: n,m<=50

对于100%的数据: n,m<=100



题目大意大概就是这样

这个题也算是祖传题了

上一届的yveh学长当时这题就没能做出来

点名批评某助教

大概讲一下思路以及心路历程

完整的代码为了(防止学弟学妹们借鉴,就不放了)

毕竟是祖传题嘛!!

大概主要是对箱子进行bfs,然后每一个点的状态存储当前的x,当前的y,当前的s(已走路程),还有上一次移动推过来的方向dir。

struct Node{
int x,y,s,dir;
};

然后每次对箱子bfs之前,都要对人进行bfs,看看能不能到箱子的四个位置,这时候上一次的dir就起作用了,可以知道人的初始位置

于是我就这样做了

不幸地TLE了

之后询问了以下周围同学,然后优化了一些步骤的先后顺序

So——速度大概快了负的百分之一吧!

我太难了

之后我就尝试了一些黑科技

强行加上头文件的O2O3Ofast优化之类的

可参考我的另一篇文章

卡常的编译命令(含O2优化)

当然还是没用啦

之后班里面的Hz同学告诉我关于vis数组的判断可以优化的方法

like this:

多次要用到vis[]时
可以用把vis改成int型,然后每次使用cnt++,如果cnt==vis[],说明此次已经遍历到了;
反之,就让vis[]=cnt;

速度好像是快了那么一点点点点

然而还是没啥用

然后,然后……

又get到一个技巧,就是每次对人进行bfs的时候,不要bfs四个方向,而是一次bfs;

因为起点都是一样的嘛,就是终点不太一样

然后一次bfs全图,再判断这个点能不能到

理论上这个可以让程序快四倍

我又交了

——————又T了

95分真的是气死人

不过我们班好多同学都卡在了95分上面;

最后的最后

我因为以前一直用的是STL里面的queue,毕竟我觉得更加方便,可以用结构体

现在——————不得不改成用数组表示队列了

确实我知道这样要快一点,但是基本上这要把整个程序都改一遍



又能咋办呢?

最后 费了好长一段时间,总算改完了

(如果不算之前的尝试吧)1Y !!!

小作业之后————感叹————STL害人!!!

真的不知道我什么时候又会真香

真香!

下面贴一点代码

关于最后表示队列的数组

int Q1[410000],Q2[410000],Q3[410000],Q4[410000],L,R;
int qx[410000],qy[410000],l,r;

箱子的bfs

void bfs(){
L=0,R=0;
for(int i=0;i<4;++i){
int nowx = th.x;
int nowy = th.y;
int nows=0;
int nowdir=i;
if(getbfs(my.x,my.y,nowx-dx[i],nowy-dy[i],th.x,th.y)){
R++;
Q1[R]=nowx,Q2[R]=nowy,Q3[R]=nows,Q4[R]=nowdir;
vis[nowdir][nowx][nowy]=true;
}
}
while(L<R){
L++;
int nowx=Q1[L];
int nowy=Q2[L];
int nows=Q3[L];
int nowdir=Q4[L];
BFS(nowx-dx[nowdir],nowy-dy[nowdir],nowx,nowy);
for(int i=0;i<4;++i){
int newsx=nowx+dx[i];
int newsy=nowy+dy[i];
int newss=nows+1;
int newsdir=i;
if(v[nowx-dx[i]][nowy-dy[i]]!=cnt) continue;
if(Map[newsx][newsy]=='S'||newsx<1||newsx>n||newsy<1||newsy>m||vis[i][newsx][newsy]==true) continue;
if(Map[newsx][newsy]=='K'){
flag=newss;
return;
}
R++;
Q1[R]=newsx,Q2[R]=newsy,Q3[R]=newss,Q4[R]=newsdir;
vis[i][newsx][newsy]=true;
}
}
return;
}

人的bfs

void BFS(const int &x,const int &y,const int &tx,const int &ty){
cnt++;
l=0,r=1;
qx[r]=x,qy[r]=y;
v[x][y]=cnt;
while(l<r){
l++;
int nowx=qx[l],nowy=qy[l];
for(int i=0;i<4;++i){
int newsx=nowx+dx[i];
int newsy=nowy+dy[i];
if(Map[newsx][newsy]=='S'||(newsx==tx&&newsy==ty)||newsx<1||newsx>n||newsy<1||newsy>m) continue;
if(v[newsx][newsy]==cnt) continue;
else{
v[newsx][newsy]=cnt;
r++;
qx[r]=newsx,qy[r]=newsy;
}
}
}
}

That's all.

SJTU T4143 推箱子的更多相关文章

  1. OC推箱子

    #include<stdio.h> #include<stdlib.h> int main(void) { char sr;//存储用户输入的指令 //绘制地图 char a[ ...

  2. c语言游戏推箱子

    前两天做了推箱子小游戏,看似简单的一个小游戏背后却 有巨大的秘密,这秘密就是一大堆逻辑. 自从学习了函数过后,的确是解决了很多问题,而且调用很方便,尽管我现在都不是很会调用. 写完一个函数,准备测试一 ...

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

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

  4. 用C#制作推箱子小游戏

    思路分析: 一.制作一个地图 二.地图中放置墙.箱子.人.目标等 三.让小人动起来完成推箱子动作 游戏制作: 1.按照上述地图制作一个地图  (12行×13列) 地图可以看做是行和列组成的,即可以看做 ...

  5. hdu.1254.推箱子(bfs + 优先队列)

    推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  6. [游戏模版17] Win32 推箱子 迷宫

    >_<:Here introduce a simple game: >_<:resource >_<:only can push a box and finally ...

  7. [转]Flash ActionScript2.0面向对象游戏开发-推箱子

    本文转自:http://www.alixixi.com/Dev/W3C/Flash/2007/2007070868666.html 概述: Flash ActionScript2.0是一种面向对向的编 ...

  8. c#部分---网吧充值系统;简易的闹钟;出租车计费;简单计算器;对战游戏;等额本金法计算贷款还款利息等;随机生成10个不重复的50以内的整数;推箱子;

    网吧充值系统namespace ConsoleApplication1 { class Program { struct huiyuan { public string name; public st ...

  9. c++、c实现推箱子小游戏

    经过四次的修改和优化,终于将推箱子这个游戏完整的写出来了,今天就像大家分享一下这个游戏的编写. 这个游戏界面的编写总的来说不困难,主要是推动箱子的算法. (1)利用数组和windows api 即可写 ...

随机推荐

  1. P-数学程序猿今天开始写博客了

    ∧          /| /\7          ≤_/      ∧. |      |         /   /      /        〉 |     Z_,<   /      ...

  2. Char、float、Double、BigDecimal

    Char初识 char: char类型是一个单一的 16 位 Unicode 字符 char 在java中是2个字节("字节"是byte,"位"是bit ,1 ...

  3. msf中arp_sweep使用报错:usbmon1:ERROR while getting interface flags:no such device

    在许多的工具使用中,会出现很多的错误,要养成先思考再去寻找帮助的习惯 在用use命令使用arp_sweep模块的时候爆出错误:usbmon1:ERROR while getting interface ...

  4. 第十九篇 同源策略与Jsonp

    同源策略 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础之上的 ...

  5. python -- 犯过的错之变量作用域

    1.写代码时发现取得变量值,会被覆盖,改为图二的写法后case_id则不会覆盖. 原因:可以理解为变量是内存中一个对象的“引用”.在函数参数传值时,变量也是内存对象的引用. 当对象为可更改对象时,是引 ...

  6. HDU 5280 BestCoder Round #47 1001:Senior's Array

    Senior's Array  Accepts: 199  Submissions: 944  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit ...

  7. Day3-T2

    原题目 奶牛Bessie的电脑总是无缘无故地被 FJ 关掉,奶牛 Bessie 非常苦恼,也非常生气.FJ 却发现了 一个很神奇的规律(别问是怎么知道的),发现 Bessie 每吃一次草,她的生气值会 ...

  8. 很多内容是转载或copy各个大佬的

    很多内容是转载或copy各个大佬的

  9. git使用代理

    在使用git科隆一个repo的时候,因为这个repo的子模块是托管在google上的,还是因为gfw导致子模块科隆不下来 只好使用代理了,那么怎么配置git使用代理呢 代码如下 因为我用的是ss所以这 ...

  10. HZNU-ACM寒假集训Day10小结 单调栈-单调队列

    数据结构往往可以在不改变主算法的前提下题高运行效率,具体做法可能千差万别,但思路却是有规律可循 经典问题:滑动窗口  单调队列O(n) POJ 2823 我开始写的: TLE 说明STL的库还是有点慢 ...