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

在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. uva10245-The Closest Pair Problem(平面上的点分治)

    解析:平面上的点分治,先递归得到左右子区间的最小值d,再处理改区间,肯定不会考虑哪些距离已经大于d的点对,对y坐标归并排序,然后从小到大开始枚举更新d,对于某个点,x轴方向只用考虑[x-d,x+d]( ...

  2. ListView之BaseAdapter

    BaseAdapter可以实现自定义的丰富子项视图,本文实现如下所示结果: 实现代码: /* ListView :列表 BaseAdapter 通用的基础适配器 * * */ public class ...

  3. UGUI 过渡动画插件,模仿NGUI的Tween (转载)

    最近在相亲,后来好朋友跟我说他写了一个好插件,于是我就把女朋友甩了,看看他的插件,可以在UGUI制作简单过渡动画. 我看了下是模仿NGUI的Tween, 我在筱程的基础上稍微改到人性化, 简单支持的让 ...

  4. mysql增量备份 percona-xtrabackup

    先说下实际环境 阿里云买的ESC跑的mysql服务,目前由于数据量过大,数据库目前有800多GB,每次全备需要等20多个小时才能够完成,然后就想到做增量备份,写下此文档 一.测试环境 [root@lo ...

  5. pat 1049 Counting Ones

    要统计1到N之间‘1’的个数,如数11包含2个1.所以当N=12时,答案为5. 思想: 找规律,假设ans[N]表示1到N的‘1’的个数,则有a[100]=(a[10]-1)*9+10+a[10]-1 ...

  6. Weblogic的Admin server进程将CPU消耗尽问题解决

    1.serverCPU被耗尽,持续100% 以下附nmon图 2.两个weblogicadmin server进程将CPU耗尽 问题:24298进程,占用百分之四千多的CPU资源 23529进程,占用 ...

  7. JSTL解析——003——core标签库02

    上一节主要讲解了<c:if/><c:choose/><c:when/><c:otherwise><c:out/>标签的使用,下面继续讲解其它 ...

  8. NFinal 视图—用户控件

    自定义控件 定义控件 以Label控件为例: 1.首先在Common文件夹下添加Label.cs文件,其中代码如下: //a.control的实体类必须继承NFinal.UserControl类 pu ...

  9. IOS开发之程序执行状态更改

    1 前言 上节我们介绍了程序执行的状态,从例子中我们可以发现处理这些状态更改的时候有明确的策略可以遵循,这次我们就来介绍一下. 2 详述 2.1 活动->不活动 使用applicationWil ...

  10. Python3.5入门学习记录-条件控制

    Python的条件控制同C#一样,都是通过一条或多条语句的执行结果(True OR False)来决定执行的代码块. if 语句 Python中if语句的一般形式如下所示: if condition_ ...