相信大家都玩过贪吃蛇游戏吧。

在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的更多相关文章

  1. Android快乐贪吃蛇游戏实战项目开发教程-01项目概述与目录

    一.项目简介 贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏. 我已经将做好的案例上传到了应用宝,无病毒.无广告,大家可以放心下载下来把玩一下.应用宝 ...

  2. 用C++实现的贪吃蛇游戏

    我是一个C++初学者,控制台实现了一个贪吃蛇游戏. 代码如下: //"贪吃蛇游戏"V1.0 //李国良于2016年12月29日编写完成 #include <iostream& ...

  3. [LeetCode] Design Snake Game 设计贪吃蛇游戏

    Design a Snake game that is played on a device with screen size = width x height. Play the game onli ...

  4. JavaScript-简单的贪吃蛇小游戏

    实现逻辑: //获取Html中的格子(行,列) //建立数组存储所有格子(x,y) //建立数组用于存储蛇身(x,y) //生成随机坐标(x,y)的函数 //随机创建蛇身并存储到蛇身数组 //创建食物 ...

  5. juery实现贪吃蛇的游戏

    今天用juery做了一个贪吃蛇的游戏,代码比较简陋,不过作为这些天学习juery的成果,非常有成就感.另外关于代码内容如有雷同不胜荣幸. 更改了下 让头和身子的颜色不一样 这样好区分些,虽然还是不怎么 ...

  6. HTML 5 背离贪吃蛇 写成了类似于屏幕校准

    中间写了改 改了写 还是没做出自己满意的效果 ,看来自己的确不是一个走前端的料子.当然h5还是学一点好一点 具体说来 就是 在canvas 的画布中 鼠标点击后画上一个圆形 然后就有随机的在画布上面出 ...

  7. 控制台游戏引擎CGE——贪吃蛇

    今天我也来发一个控制台游戏.先看图: 缘起 LZ是一个有严重拖延症的人,表现的形式就是隔一段时间就要刷一刷博客园. 这不前几天,看到了魏大师<使用Lua脚本语言开发出高扩展性的系统...> ...

  8. 原生JS制作贪吃蛇小游戏

    感情都在代码里,来,干了!... <!doctype html> <html> <head> <meta http-equiv="Content-T ...

  9. 基于AT89C51单片机的贪吃蛇电子游戏(仿真)

    有关贪吃蛇的历史发展可以看一下这个网址,贪吃蛇最初的设计和现在并不相同..http://www.techweb.com.cn/internet/2013-02-21/1278055.shtml 该项目 ...

随机推荐

  1. CDT+Eclipse代码自动提示

    1.查看GCC的版本:$gcc -v————————————————————————gcc version 4.4.6 20110731 (Red Hat 4.4.6-3) (GCC)———————— ...

  2. 脚本控制向Android模拟拨打电话,发送短信,定位设置功能

    做行为触发的时候要向模拟器实现拨打电话,发送短信,定位设置的的功能,可以很方便通过telnet localhost  5554实现. 写个脚本很快的搞定了.网上资料很多,脚本的很少,也所积点德啦. 写 ...

  3. C++中单链表的建立和操作

    准备数据 准备在链表操作中需要用到的变量及数据结构 示例代码如下: struct Data //数据结点类型 { string key; //关键字 string name; int age; }; ...

  4. poj 3320 Jessica's Reading Problem(尺取法)

    Description Jessica's a very lovely girl wooed by lots of boys. Recently she has a problem. The fina ...

  5. JQuery 动画之 广告

    html页面: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head&g ...

  6. Java连接Oracle数据库的示例代码

    最基本的Oracle数据库连接代码(只针对Oracle11g): 1.右键项目->构建路径 ->配置构建路径,选择第三项“库”,然后点击“添加外部Jar”,选择 “D:\Oracle\ap ...

  7. iOS更新之DFU模式和恢复模式

    DFU模式和恢复模式的区别:DFU模式是在iPhone固件引导启动之前进行恢复的模式.所以用DFU模式刷机一般比较干净,不会有任何垃圾文件.想当于电脑重新格式化之后再安装系统. DFU模式进入方法:1 ...

  8. uva 310 L--system(隐式图搜索+字符串处理)

     L-system  A D0L (Deterministic Lindenmayer system without interaction) system consists of a finite ...

  9. 百度地图 Android SDK - 检索功能使用的简单演示样例

    百度地图 SDK 不仅为广大开发人员提供了炫酷的地图展示效果.丰富的覆盖物图层,更为广大开发人员提供了多种 LBS 检索的能力. 通过这些接口,开发人员能够轻松的訪问百度的 LBS 数据,丰富自己的移 ...

  10. 包含深度学习常用框架的Docker环境

    相关的代码都在Github上,请参见我的Github,https://github.com/lijingpeng/deep-learning-notes 敬请多多关注哈~~~ All in one d ...