UESTC_贪吃蛇 CDOJ 709
相信大家都玩过贪吃蛇游戏吧。
在n×m的迷宫中,有着一条长度不超过9的贪吃蛇,它已经将所有的食物吃光了,现在的目标是移动到出口。
它走的时候不能碰到自己的身体,也不能碰到墙壁。(如果贪吃蛇的长度>3并且下一步要走到自己的尾部,是合法的)
问它能不能走到出口,如果能,最少要移动几步?
Input
数据包含多组数据,请读入到文件末尾EOF
每组数据第一行包含两个整数n,m(1≤n,m≤15)代表迷宫的大小。
接下来n行,每行包含一个长度为m的字符串,来表示迷宫。
字符串中仅包含.
、#
、@
、1
~ 9
、.
代表空地 #
代表墙 数字一定是1∼k 连续的k个数字,代表贪吃蛇,1代表它的头,k代表它的尾,数据保证数字i一定和数字i+1在迷宫中相邻。 @
代表出口。
Output
对于每组数据,先输出Case #i:
,i为当前数据组数。
接下来一个数,代表贪吃蛇最少需要移动的步数,若无法移动出去输出-1
解题报告
主要是判重问题
肯定不能vis[15][15].....x9
内存依然爆炸,其实大部分都是没有使用的,因此我们考虑到
蛇的每截身体较于前面一截只有 4 种状态,我们用4进制来压缩蛇的身体,这样就能存下了,注意蛇头可以移动到最后一截身体所在的位置.
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int Max = ;
char G[Max+][Max+];
bool vis[][][];
int R,C,targetx,targety,n;
// n is snake-body num
int dir[][] ={-,,,,,-,,};
int caculate[] ={,,,,,,,};
typedef struct status
{
int x[];
int y[];
int step;
}; status ori;
status thisq[]; int getturn(int x,int y,int x0,int y0){
if (x - x0 == ) return ;
if (x - x0 == -) return ;
if (y - y0 == ) return ;
if (y - y0 == -) return ;
printf("Error at get turn!\n");
} int getcode(status& x){
int buffer[];
int code = ;
for(int i = ;i<n;++i)
code += getturn(x.x[i],x.y[i],x.x[i-],x.y[i-]) * caculate[i-];
return code;
} bool judge(status& x){
int tx = x.x[];
int ty = x.y[];
for(int i = ;i<n;++i)
if(x.x[i] == tx && x.y[i] == ty)
return false;
return true;
} bool dfs1(int x,int y){
int front = ,rear = ;
int q[][];
bool evis[][];
memset(evis,false,sizeof(evis));
evis[x][y] = true;
q[rear][] = x;
q[rear++][] = y;
while(front < rear)
{
int tx = q[front][];
int ty = q[front++][];
if (tx == targetx && ty == targety) return true;
for(int i = ;i<;++i)
{
int newx = tx + dir[i][];
int newy = ty + dir[i][];
if (!evis[newx][newy] && G[newx][newy] != '#' && newx < R && newx >= && newy < C && newy >=)
{
q[rear][] = newx;
q[rear++][] = newy;
evis[newx][newy] = true;
}
}
} return false;
} int dfs(){
int front = ,rear = ;
ori.step = ;
thisq[rear++] = ori;
vis[ori.x[]][ori.y[]][getcode(ori)] = true;
while(front < rear)
{
int tx = thisq[front].x[];
int ty = thisq[front].y[];
int step = thisq[front].step;
if (tx == targetx && ty == targety) return step;
for(int i = ;i < ;++i)
{
int newx = tx + dir[i][];
int newy = ty + dir[i][];
int newstep = step+;
if (newx >= R || newx < || newy >=C || newy < || G[newx][newy] == '#')
continue;
status newst;
newst.x[] = newx;
newst.y[] = newy;
newst.step = step + ;
for(int j=;j<n;++j)
{
newst.x[j] = thisq[front].x[j-];
newst.y[j] = thisq[front].y[j-];
}
if (!vis[newst.x[]][newst.y[]][getcode(newst)] && judge(newst))
{
thisq[rear++] = newst;
vis[newst.x[]][newst.y[]][getcode(newst)] = true;
}
} front++;
} return -;
} bool input(){
while(scanf("%d%d%*c",&R,&C)==)
{
n = ;
memset(vis,false,sizeof(vis));
for(int i = ;i<R;++i)
gets(&G[i][]);
for(int i = ;i<R;++i)
for(int j = ;j<C;++j)
if(G[i][j] == '@')
{
targetx = i;
targety = j;
}
else if(G[i][j] <= '' && G[i][j] >= '')
{
ori.x[G[i][j] - ''] = i;
ori.y[G[i][j] - ''] = j;
n ++ ;
}
return true;
}
return false;
} int main(int argc,char * argv[]){
int T = ;
while(input() == true)
{
if(!dfs1(ori.x[],ori.y[]))
{
cout << "Case #"<< T++ <<": -1" <<endl;
continue;
}
int ans = dfs();
cout << "Case #"<< T++ <<": "<< ans <<endl;
}
return ;
}
UESTC_贪吃蛇 CDOJ 709的更多相关文章
- Android快乐贪吃蛇游戏实战项目开发教程-01项目概述与目录
一.项目简介 贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏. 我已经将做好的案例上传到了应用宝,无病毒.无广告,大家可以放心下载下来把玩一下.应用宝 ...
- 用C++实现的贪吃蛇游戏
我是一个C++初学者,控制台实现了一个贪吃蛇游戏. 代码如下: //"贪吃蛇游戏"V1.0 //李国良于2016年12月29日编写完成 #include <iostream& ...
- [LeetCode] Design Snake Game 设计贪吃蛇游戏
Design a Snake game that is played on a device with screen size = width x height. Play the game onli ...
- JavaScript-简单的贪吃蛇小游戏
实现逻辑: //获取Html中的格子(行,列) //建立数组存储所有格子(x,y) //建立数组用于存储蛇身(x,y) //生成随机坐标(x,y)的函数 //随机创建蛇身并存储到蛇身数组 //创建食物 ...
- juery实现贪吃蛇的游戏
今天用juery做了一个贪吃蛇的游戏,代码比较简陋,不过作为这些天学习juery的成果,非常有成就感.另外关于代码内容如有雷同不胜荣幸. 更改了下 让头和身子的颜色不一样 这样好区分些,虽然还是不怎么 ...
- HTML 5 背离贪吃蛇 写成了类似于屏幕校准
中间写了改 改了写 还是没做出自己满意的效果 ,看来自己的确不是一个走前端的料子.当然h5还是学一点好一点 具体说来 就是 在canvas 的画布中 鼠标点击后画上一个圆形 然后就有随机的在画布上面出 ...
- 控制台游戏引擎CGE——贪吃蛇
今天我也来发一个控制台游戏.先看图: 缘起 LZ是一个有严重拖延症的人,表现的形式就是隔一段时间就要刷一刷博客园. 这不前几天,看到了魏大师<使用Lua脚本语言开发出高扩展性的系统...> ...
- 原生JS制作贪吃蛇小游戏
感情都在代码里,来,干了!... <!doctype html> <html> <head> <meta http-equiv="Content-T ...
- 基于AT89C51单片机的贪吃蛇电子游戏(仿真)
有关贪吃蛇的历史发展可以看一下这个网址,贪吃蛇最初的设计和现在并不相同..http://www.techweb.com.cn/internet/2013-02-21/1278055.shtml 该项目 ...
随机推荐
- bzoj1615 [Usaco2008 Mar]The Loathesome Hay Baler麻烦的干草打包机
Description Farmer John新买的干草打包机的内部结构大概算世界上最混乱的了,它不象普通的机器一样有明确的内部传动装置,而是,N (2 <= N <= 1050)个齿轮互 ...
- 【剑指offer】面试题35:第一个只出现一次的字符
题目: 在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符的位置.若为空串,返回-1.(书上是要求返回字符) 思路: 第一遍扫描保存下每个字符出现的 ...
- UIImageView圆角,自适应图片宽高比例,图片拉伸,缩放比例和图片缩微图
/* 设置圆角,通过layer中的cornerRadius和masksToBounds即可. 自适应图片宽高比例.通过UIViewContentModeScaleAsp ...
- 改动mac环境变量,并配置gradle
由于项目中要用到gradle命令,可是没有配置环境变量.这里记录一下解决过程. 过程例如以下: 1. 启动终端Terminal 2. 进入当前用户的home文件夹 输入cd ~ 3. 创建.bash_ ...
- NuGet学习笔记(3)——搭建属于自己的NuGet服务器(转)
在上一篇NuGet学习笔记(2) 使用图形化界面打包自己的类库 中讲解了如何打包自己的类库,接下来进行最重要的一步,从零开始搭建属于自己的NuGet服务器,诚然园子里及其它很多地方已经有完全写好的Nu ...
- C#多线程之Parallel中 类似于for的continue,break的方法
好久没写东西了,终于找到点知识记录下... 利用ParallelLoopState对象来控制Parallel.For函数的执行,ParallelLoopState对象是由运行时在后台创建的: Para ...
- Android零碎知识点总结
1 简单的跨进程通信可以用Messenger类,不用AIDL. 2 当一个Service没有action时,它默认是exported="false"的,其它进程用它的包名和类名构造 ...
- startActivityForResult中回调setResult注意事项
读 http://www.cnblogs.com/lijunamneg/archive/2013/02/05/2892616.html 有感 文中提出了一个核心问题: Android activity ...
- Javascript的事件委托
在谈js的事件委托之前,先来简单说说js事件的一些基础知识吧. 什么是事件?Javascipt与HTML之间的交互是通过事件实现的.事件,就是文档或浏览器中发生的一些特定的交互瞬间. 什么是事件流?事 ...
- 控制点:ControlPoint
位于control:Points面板下,kitControl面板的ControlPallette中也存在控制点. 控制点是什么呢?一个数据值.一个传感器的值.比如,温度值,风速值,压力值,光照值,开关 ...