解题思路:这道题一开始的想法就是状态压缩,即考虑如何判重,由于蛇并非是直线的,所以想到了以每一个点的上下左右共四个

值来表示相对位置。最开始想如何用四进制来表示它,无语。。。。。还是题目做少了,直接用两位来表示一个点即可(两位的二

进制数可以表示0-3)。剩下的关键就是判断蛇头会不会与蛇尾发生碰撞,详细的就看代码吧。。

整体的思路还是比较简单,但是代码很复杂,一般这种复杂点的搜索题代码都挺长的,所以很容易出错,不过可以用A*算法,而且

确实比朴素的算法要快,暂时还没想清楚怎么做。。。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;const int MAX_S = (1 << 14) + 100;
const int MAX_N = 20 + 2;
const int INF = (1 << 29);
struct State
{int x, y, dis, s;State(int x = 0, int y = 0, int dis = 0, int s = 0) : x(x), y(y), dis(dis), s(s) {};
};
struct Point
{int x, y;
};
int N, M, res, L;
int vis[MAX_N][MAX_N][MAX_S];
int fx[4] = {-1, 0, 1, 0};
int fy[4] = {0, 1, 0, -1};
bool _map[MAX_N][MAX_N];
Point pos[MAX_N * MAX_N];
queue <State> Q;int get_start()
{int dir, dx, dy, s = 0;for(int i = L - 1; i > 0; i--){dx = pos[i].x - pos[i - 1].x, dy = pos[i].y - pos[i - 1].y;if(dx == 0 && dy == 1)dir = 1;else if(dx == 0 && dy == -1)dir = 3;else if(dx == -1 && dy == 0)dir = 0;else if(dx == 1 && dy == 0)dir = 2;s = s << 2;s = s | dir;}return s;
}
int get_next_state(int i, int s)
{int dir;int k = (1 << ((L - 1) << 1)) - 1;int dx = 0, dy = 0;dx = dx - fx[i], dy = dy - fy[i];if(dx == 0 && dy == 1)dir = 1;else if(dx == 0 && dy == -1)dir = 3;else if(dx == -1 && dy == 0)dir = 0;else if(dx == 1 && dy == 0)dir = 2;s = s << 2;s = s | dir;s = s & k; // 去除高位部分return s;
}bool judge_code(int x, int y, int pre_x, int pre_y, int s)
{int dir;for(int i = 0; i < L - 1; i++){dir = 3;dir = dir & s;s = s >> 2;if(x == pre_x + fx[dir] && y == pre_y + fy[dir])return false;pre_x = pre_x + fx[dir], pre_y = pre_y + fy[dir];}return true;
}void BFS()
{State a;int dx, dy, s;while(!Q.empty()){a = Q.front();Q.pop();for(int i = 0; i < 4; i++){dx = a.x + fx[i], dy = a.y + fy[i];s = get_next_state(i, a.s);if(dx > 0 && dy > 0 && dx <= N && dy <= M && !vis[dx][dy][s] && !_map[dx][dy] && judge_code(dx, dy, a.x, a.y, a.s)){if(dx == 1 && dy == 1){res = a.dis + 1;return ;}vis[dx][dy][s] = 1;Q.push(State(dx, dy, a.dis + 1, s));}}}
}int main()
{int s = 0, _case = 0;State _start;while(scanf("%d%d%d", &N, &M, &L), N + M + L){res = INF;memset(_map, 0 , sizeof(_map));memset(vis, 0 , sizeof(vis));for(int i = 0; i < L; i++)scanf("%d%d", &pos[i].x, &pos[i].y);int K, u, v;scanf("%d", &K);for(int i = 0; i < K; i++){scanf("%d%d", &u, &v);_map[u][v] = 1;}if(pos[0].x == 1 && pos[0].y == 1){printf("Case %d: 0\n", ++_case);continue;}s = get_start();Q.push(State(pos[0].x, pos[0].y, 0, s));vis[pos[0].x][pos[0].y][s] = 1;BFS();if(res == INF)printf("Case %d: -1\n", ++_case);elseprintf("Case %d: %d\n", ++_case, res);while(!Q.empty())Q.pop();}return 0;
}

poj 1324(BFS+状态压缩)相关推荐

  1. BFS+状态压缩 hdu-1885-Key Task

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1885 题目意思: 给一个矩阵,给一个起点多个终点,有些点有墙不能通过,有些点的位置有门,需要拿到相应 ...

  2. csu 1536 Bit String Reordering(模拟 bfs+状态压缩)

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1536 题意: 输入n个只为 0或1 的数 形成一个排列 再输入m个数 每个数代表 目标排列 (样例 ...

  3. BFS + 状态压缩总结

    BFS + 状态压缩使用条件 求最短路径时,一般来说会优先考虑使用BFS算法.BFS算法在广度优先搜索的过程中会有一个类似vis的数组去重,避免重复访问 但是在一些情况下,题目需要求最短路径的同时,有 ...

  4. nyist 999 师傅又被妖怪抓走了 【双广搜 || BFS +状态压缩】

    题目:nyist 999 师傅又被妖怪抓走了 分析:在一个图中只要看到D点和E点就行的最小步数,看到的定义是:也就是说两个人在同一行或者同一列,并且中间没有障碍物或者没有其他人就可以看到对方. 所以可 ...

  5. hdu 1429 胜利大逃亡(续) bfs+状态压缩

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  6. POJ - 3279 Fliptile(状态压缩+位运算+暴力)

    题目链接:点击查看 题目大意:给出一个n*m的01矩阵,为了好描述,我们设0和1是两个相反的状态,我们的目标是要将整个矩阵全部变成1,现在我们可以将某一个点(x,y)更改为相反的状态,不过相应的该点周 ...

  7. 2021-08-06 leetcode每日一题 BFS+状态压缩,无向图的

    访问所有节点的最短路径 存在一个由 n 个节点组成的无向连通图,图中的节点按从 0 到 n - 1 编号. 给你一个数组 graph 表示这个图.其中,graph[i] 是一个列表,由所有与节点 i ...

  8. bfs+状态压缩dp

    题意:       给你一个地图,问你吧所有的隧道都走完的最小费用,起点不固定,穿越隧道的时间不计,在隧道外边每移动一步花费一秒. 思路:       先bfs求出所有dis[i][j](i的终点和j ...

  9. BZOJ1195[HNOI2006]最短母串——AC自动机+BFS+状态压缩

    题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 输入 第一行是一个正整数n(n<=12),表示给定的字符串的 ...

最新文章

  1. android危险权限分组,Android 6.0权限请求相关及权限分组方法
  2. Winform中实现ZedGraph新增自定义Y轴上下限、颜色、标题功能
  3. html点击按钮弹出悬浮窗_网课助手1.0 支持悬浮窗搜题等多功能
  4. 文献学习(part88)--Graph Learning for Multiview Clustering
  5. 2016蓝桥杯省赛---java---B---1(有奖猜谜)
  6. 关于csv文件转化为张量
  7. Node.js编写CLI的实践
  8. java常用8种 设计模式
  9. roseha linux,RoseHA 9.0 for Linux快速安装说明_v2.0-2015-04.pdf
  10. ant-design-vue 的颜色选择器
  11. matlab入门(适合初学者)
  12. 人工智能挑战教师角色独特性 与教育教学融合显现独特优势
  13. 2015年第六届C/C++ B组蓝桥杯省赛真题
  14. MySQL - java.sql.SQLException: Data truncated for column ‘xx‘ at row 1
  15. Linux挂载Windows网络共享文件夹
  16. 从零开始之驱动发开、linux驱动(四十、Linux common clock framework(5)_使用举例)
  17. 考研政治与专业课总结(持续更新)
  18. 重磅!谷歌2020学术指标发布:CVPR排名超Cell和Nature子刊,ACL首进TOP 100
  19. xp安装python3.7_Python入门七:安装支持WinXp运行的Python及环境配置
  20. pako java_基于pako.js实现gzip的压缩和解压功能示例

热门文章

  1. 湘财证券罗叶:数字化在金融领域的应用与实践,从“我觉得”到“用户觉得”...
  2. Android•Lottie动画库填坑记
  3. Application Virtualization 4.5 部署之(三)(
  4. Java_Notes_基础排序总结与对比
  5. 第二阶段—个人工作总结03
  6. Java虚拟机——类加载机制
  7. 最新OpenSSL漏洞CCS注入及升级修复
  8. [资料]有关MS SQL 2000安全问题
  9. 苹果笔记本电脑电池保养细则
  10. st edmunds和emmanuel college