POJ1324贪吃蛇(状态压缩广搜)
题意:
给你一个地图,有的地方能走,有的地方不能走,然后给你一条蛇,问你这条蛇的头部走到1,1的位置的最少步数,注意,和贪吃蛇不太一样,就是蛇咬到自己身体的那个地方,具体怎么不一样自己模拟下那个数据就明白了。
思路:
敲了挺长时间的,可能是刚过完年回来半个月没写代码手有点生了,一开始有个SB的想法就是我感觉只标记蛇的头部和尾部就行了,索然在敲之前已经动摇了,但是还是硬着头皮敲了一个代码,果断WA了,然后就是敲正确的方式(估计我的也不是标准的,以为我是5000MS g++过的,直接踩线过的节奏,里面自己平感觉优化了一些),我是mark[x][y][v],x,y是蛇头坐标,v是蛇身体的状态,状态压缩(4进制的(其实感觉三进制也行,然后在加个蛇的方向,没尝试去写,状态少点,没准会快点))思路就是首先从蛇头后的第一个开始相对于蛇头的位置,上下左右,然后是蛇头后第二个相对于第一个的位置,上下左右,这样就可以用
x y v三个int来表示条蛇的位置和状态了,我的跑了5000MS,其实我感觉还有一个地方可以优化,就是我判断的时候浪费了l(蛇长度)的时间,其实我们可以空间换时间,我觉得可以在每个结构体里面开个二维的map来标记当前的蛇的身体(为了判断撞到自己身体用的)更新这个O(1)的时间,至于蛇状态之间的转换,可以直接用取余的方法把最高位去掉,然后*4,然后再把第一位填上,这个操作的时间复杂度也是O(1)的,对于我的总时间复杂度的话T的话优化后是大约 T/L的,这个是理论值,具体的我也没去敲,我是这么想的,有兴趣的可以敲下试试,最好就是用三个方向,然后在空间换时间去优化,估计能快点。但是想刷排名还是用A*吧,虽然我现在不会。
#include<queue>
#include<stdio.h>
#include<string.h>
#define N 20 + 1
#define M 16384
using namespace std;
typedef struct
{
int x ,y;
}NODE;
typedef struct
{
int x ,y ,v ,t;
}P;
P tou ,xin;
NODE S[10];
int map[N][N] ,n ,m ,l;
int mark[N][N][M];
int dir[4][2] = {-1 ,0 ,1 ,0 ,0 ,-1 ,0 ,1};
int GetXinV()//得到xin.v并且判断是否撞到自己
{
int tmp = 4;
int x = tou.x ,y = tou.y;
for(int i = 2 ;i <= l ;i ++)
{
int now = tou.v % tmp / (tmp / 4);
if(i <= l - 1) xin.v += now * tmp;
x = x + dir[now][0];
y = y + dir[now][1];
if(x == xin.x && y == xin.y)
return 0;
tmp *= 4;
}
return 1;
}
bool ok(int x ,int y)
{
return x >= 1 && x <= n && y >= 1 && y <= m && !map[x][y];
}
int BFS()
{
memset(mark ,0 ,sizeof(mark));
mark[xin.x][xin.y][xin.v] = 1;
queue<P>q;
q.push(xin);
while(!q.empty())
{
tou = q.front();
q.pop();
//printf("%d %d %d**\n" ,tou.x ,tou.y ,tou.v);
if(tou.x == 1 && tou.y == 1)
return tou.t;
for(int i = 0 ;i < 4 ;i ++)
{
xin.x = tou.x + dir[i][0];
xin.y = tou.y + dir[i][1];
xin.t = tou.t + 1;
xin.v = i ^ 1;
if(!ok(xin.x ,xin.y)) continue;
if(GetXinV())
{
if(!mark[xin.x][xin.y][xin.v])
{
mark[xin.x][xin.y][xin.v] = 1;
if(xin.x == 1 && xin.y == 1)
return xin.t;
q.push(xin);
}
}
}
}
return -1;
}
int main ()
{
int i ,x ,y ,cas = 1;
while(~scanf("%d %d %d" ,&n ,&m ,&l) && n + m + l)
{
for(i = 1 ;i <= l ;i ++)
scanf("%d %d" ,&S[i].x ,&S[i].y);
memset(map ,0 ,sizeof(map));
scanf("%d" ,&i);
while(i--)
{
scanf("%d %d" ,&x ,&y);
map[x][y] = 1;
}
xin.x = S[1].x ,xin.y = S[1].y;
xin.t = xin.v = 0;
int tmp = 1;
for(i = 2 ;i <= l ;i ++)
{
int now;
if(S[i].x - S[i-1].x == 1) now = 1;
else if(S[i].x - S[i-1].x == -1) now = 0;
else if(S[i].y - S[i-1].y == 1) now = 3;
else now = 2;
xin.v += now * tmp;
tmp *= 4;
}
printf("Case %d: %d\n" ,cas ++ ,BFS());
}
}
POJ1324贪吃蛇(状态压缩广搜)的更多相关文章
- hdu5025 状态压缩广搜
题意: 悟空要救唐僧,中途有最多就把钥匙,和最多五条蛇,要求就得唐僧并且拿到所有种类的钥匙(两个1只拿一个就行),拿钥匙i之前必须拿到钥匙i-1,打蛇多花费一秒,问救出唐僧并且拿到所有种类 ...
- UVA 10047 The Monocycle (状态记录广搜)
Problem A: The Monocycle A monocycle is a cycle that runs on one wheel and the one we will be consi ...
- UVa 10047 自行车 状态记录广搜
每个格子(x,y,drection,color) #include<iostream> #include<cstdio> #include<cstring> #in ...
- POJ2688状态压缩(可以+DFS剪枝)
题意: 给你一个n*m的格子,然后给你一个起点,让你遍历所有的垃圾,就是终点不唯一,问你最小路径是多少? 思路: 水题,方法比较多,最省事的就是直接就一个BFS状态压缩暴搜就行 ...
- hdu 5025 Saving Tang Monk 状态压缩dp+广搜
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092939.html 题目链接:hdu 5025 Saving Tang Monk 状态压缩 ...
- hdu 5094 Maze 状态压缩dp+广搜
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092176.html 题目链接:hdu 5094 Maze 状态压缩dp+广搜 使用广度优先 ...
- ACM/ICPC 之 BFS+状态压缩(POJ1324(ZOJ1361))
求一条蛇到(1,1)的最短路长,题目不简单,状态较多,需要考虑状态压缩,ZOJ的数据似乎比POj弱一些 POJ1324(ZOJ1361)-Holedox Moving 题意:一条已知初始状态的蛇,求其 ...
- poj 1324 状态广搜
其实就是我们经常玩的贪吃蛇. 不过现在我们优先蛇的头的话,要用一个巧妙的哈希来把蛇的身体表达出来,那么就可以用一个4进制的数字来表示,蛇的身体长度最多不超过8,所以最多是2^7种状态. #includ ...
- Oj 24260: Lilypad Pond (神奇广搜题,状态搜索)
题目 为了让奶牛们娱乐和锻炼,约翰建造了一个美丽的池塘.这个池塘是矩形的,可以分成M×N个方格.一些格子是坚固得令人惊讶的莲花,还有一些是岩石,其余的只是美丽,纯净,湛蓝的水.贝西正在练习芭蕾舞,她站 ...
随机推荐
- 简单的ssm练手联手项目
简单的ssm练手联手项目 这是一个简单的ssm整合项目 实现了汽车的品牌,价格,车型的添加 ,修改,删除,所有数据从数据库中拿取 使用到了jsp+mysql+Mybatis+spring+spring ...
- django Form 效验
Django 登入效验 .py from django import forms from student import models from django.core.exceptions impo ...
- 关于 PDB 文件你需要知道什么?
引言 大多数人知道 PDB 文件是用来帮助我们 debug 的,但也仅此而已. 本文主要介绍当你遇到 PDB 文件时(windows 开发中),你必须要知道的内容. 重要的事情说三遍 PDB 文件和源 ...
- JAVA使用Collator对中文排序
首先创建一个集合 public static List<String> init() { List<String> list = new ArrayList<String ...
- [HEOI2014] 人人尽说江南好
[HEOI2014] 人人尽说江南好 题目大意:一个博弈游戏,地上\(n\)堆石子,每堆石子有\(1\)个,每次可以合并任意两个石子堆\(a,b\),要求\(a + b \leq m\),问先手赢还是 ...
- Nodejs学习笔记(4) 文件操作 fs 及 express 上传
目录 参考资料 1. fs 模块 1.1 读取文件fs.readFile 1.2 写入文件fs.writeFile 1.3 获取文件信息fs.stat 1.4 删除文件fs.unlink 1.5 读取 ...
- 学习Python的书籍——入门到进阶
入门读物 <Python基础教程>(Beginning Python From Novice to Professional) <Python学习手册>(Learning Py ...
- P1426 小鱼会有危险吗(JAVA语言)
题目描述 有一次,小鱼要从A处沿直线往右边游,小鱼第一秒可以游7米,从第二秒开始每秒游的距离只有前一秒的98%.有个极其邪恶的猎人在距离A处右边s米的地方,安装了一个隐蔽的探测器,探测器左右x米之内是 ...
- Git - 使用命令和P4Merge进行diff
P4Merge P4Merge是Git的一个第三发Diff和Merge工具(可视化冲突解决工具). 下载地址: https://www.perforce.com/downloads/visual-me ...
- JS中dom操作的事件
Click--点击事件 优先级:dom.onclick 高于标签上的onClick属性 监听事件 --不会覆盖前面的事件效果 dom.addEventListener() 括号里面有三个参数 1 ...