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 该项目 ...
随机推荐
- unix c 09
IPC - 进程间通信 文件/信号/管道/共享内存/消息队列/信号量集/网络 XSI IPC (共享内存.消息队列和信号量集) 使用方式 非常的类似. 共享内存的使用步骤: 1 生 ...
- MVC 增加统一异常处理机制
原文地址:http://www.cnblogs.com/leoo2sk/archive/2008/11/05/1326655.html 摘要 本文将对“MVC公告发布系统”的发布公告功能添加 ...
- jsp判断session中的值
方法有两种: 假设,此session的名字叫adminAccount 1.EL表达式 <script type="text/javascript"> if($.trim ...
- javascript 继承机制设计思想
作者: 阮一峰 原文链接:http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_java ...
- android 推断Apk是否签名和 签名是否一致
推断Apk是否签名 用命令:jarsigner -verify -verbose -certs <apk文件> 假设有Android Debug字樣就是debug 假设已经签名: [证书的 ...
- javascript 切换动画
function startMove(obj, json, fn) { clearInterval(obj.timer); obj.timer = setInterval(function() { v ...
- EasyuiCombobox三级联动
有许多刚接触Easyui中Combobox控件的朋友可能都会遇到的问题:如何将Combobox做成三级联动? 先本人有个三级联动的案例给大家参考参考,经测试能通过.注意Combobox绑定的数据是Js ...
- Entity Framework数据库迁移
1.启用数据迁移: enable-Migrations2.增加一条数据库迁移指令:add-Migrations 必须带上一个版本名称,比如AddUsernamePassword完整的指令:add-Mi ...
- 迁移google code上的项目到本地版本库
今年五月份以来就已经连接不上google code了,翻*墙又极度不稳定,在忍受了几个月之后终于决定将项目搬离google code;经过研究之后终于实现了搬迁到本地,最后总结成下文.一者期望对有需要 ...
- CDZSC_2015寒假新人(2)——数学 G
G - G Time Limit:3000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status ...