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个方格.一些格子是坚固得令人惊讶的莲花,还有一些是岩石,其余的只是美丽,纯净,湛蓝的水.贝西正在练习芭蕾舞,她站 ...
随机推荐
- 树莓派4b通过外接ssd硬盘启动系统失败的排查和解决
树莓派4b通过外接ssd硬盘启动系统失败,症状: 屏幕卡在黑屏或提示 mmc1:Controller never released inhibit bit(s).... 先说如何设置硬盘启动,后面是解 ...
- [Elementary Mechanics Using Python-02]Feather in tornado
Problem 9.17 Feather in tornado. In this project you will learn to use Newton's laws and the force m ...
- 再来认识一下 Java 序列化
前言 在面试中,Java 序列化被问到的几率还是挺高的.所以搜集了 Java 序列化常见的问题,由浅入深的帮助大家进一步学习和理解. 序列化基础知识 什么是序列化? Java 序列化是 JDK 1.1 ...
- C#使用OpenCV剪切图像中的圆形和矩形
前言 本文主要介绍如何使用OpenCV剪切图像中的圆形和矩形. 准备工作 首先创建一个Wpf项目--WpfOpenCV,这里版本使用Framework4.7.2. 然后使用Nuget搜索[Emgu.C ...
- CVE-2020-1938 -Tomcat-AJP任意文件读取/包含
为什么这个漏洞被称作 Ghostcat(幽灵猫)? 这个漏洞影响全版本默认配置下的 Tomcat(在我们发现此漏洞的时候,确认其影响 Tomcat 9/8/7/6 全版本,而年代过于久远的更早的版本未 ...
- WPF 基础 - 在模板中找元素
1. 在 ControlTemplate 中寻找元素 <Window.Resources> <ControlTemplate x:Key="cTmp"> & ...
- 你想知道的 std::vector::push_back 和 std::vector::emplace_back
引言 C++ 11 后,标准库容器 std::vector 包含了成员函数 emplace 和 emplace_back.emplace 在容器指定位置插入元素,emplace_back 在容器末尾添 ...
- mongodb为什么比mysql效率高
首先是内存映射机制,数据不是持久化到存储设备中的,而是暂时存储在内存中,这就提高了在IO上效率以及操作系统对存储介质之间的性能损耗.(毕竟内存读取最快) 其次,NoSQL并不是不使用sql,只是不使用 ...
- FTT简单入门板子
DFT : 1 #include <cstdio> 2 #include <iostream> 3 #include <cmath> 4 #include < ...
- gstreamer常用命令
由于有好一段时间没做GStreamer相关项目了,早前的一些记录需要做下记录,以待需要的时候查阅. 还是分几个小节来介绍吧,这样思路清晰一点.(格式有点乱,没时间整理,读者自行脑补) 1. 播放视频. ...