[状压DP][BFS][哈希]JZOJ 3243 Cube
Description
1.密室是一个呈m×n网格的长方形,地面有六个格子被上了色;
2.密室地面部分格子可能有障碍物;
3.密室的某一格有一个六面都没上色的立方体;
4.当立方体滚动到相邻无障碍物的格子,如果立方体接触地面的一面没有颜色而地面有颜色,则该颜色会从地面转移到立方体上;如果立方体接触地面的一面有颜色而地面没有颜色,则该颜色会从立方体转移到地面上;如果立方体接触地面的一面和地面都有颜色,则两者的颜色都不会转移。
5.当立方体滚动到密室的指定地点,如果立方体六面都被涂上了颜色,则传送门就会开启,让你逃离这个密室。
由于时间紧迫,你必须借助计算机的力量,算出立方体最少滚动几次就可以让你逃离这个密室。
Input
‘.’:该格子是空白的;
‘#’:该格子有障碍物;
‘P’:该格子是上色的;
‘C’:立方体就在这个格子;
‘G’:能让你逃离密室的指定地点。
整个密室保证正好有6个格子是‘P’,1个格子是‘C’,1个格子是‘G’,‘.’的格子不超过12个。
Output
对以下第一个样例,立方体最少只需要滚动10次(下右右上右右下左右左)。
Sample Input
输入1: 2 5 C.PPP PPPG. 输入2: 4 5 C.... G##.P .##PP ..PPP 输入3: 3 3 PPP PCP PG. 输入4: 2 10 .PPPCPPP.. ....G.....
Sample Output
输出1: 10 输出2: 23 输出3: 15 输出4: 21
Data Constraint
分析
今日最难,一个旗鼓相当的对手
首先别被总点数迷惑了,总点数400个,但输入要求告诉我们,能走的点包括起点和终点及颜色,加起来不超过20个
那么我们可以考虑状压,给每个点标号,状态表示哪些点有颜色
这仅仅是图上的状态而已!因为立方体会带走颜色,所以另设一个6位状态,表示立方体当前每个面是否有颜色,建议在写的时候用记事本记着,忘掉了的话转移转死了
两种状态需要放在一起,所以整个状态26位,后6位位立方体状态,前20位为图上状态
然后我们考虑到,会有重复的状态,可是光是这个状态重复不够,有时图上和立方体一样,但是立方体位置不一样!
重复的状态可用哈希加邻接表(或指针)解决
最恶心的部分就是当你的立方体移动时,你的6位颜色状态全部要变一波,一坨位运算堆在一起
同时注意判断一下,当颜色状态中的下面状态与当前立方体在图上位置的状态不一样(一个有颜色一个没颜色)时,需要给他们变状态
空间别开爆了,我12Wkb刚好卡过去
#include <iostream> #include <cstdio> #include <cstring> #include <memory.h> #include <queue> #include <cstdlib> using namespace std; const int N=4e2+10; const int P=388211; struct SS {int u,S; }; struct QS {SS s;int dep; }; struct Graph {int v,nx; }e[10000000]; int cnt; int n,m; char c[N][N]; int id[N][N],icnt,g[21][4]; int sx,sy,tx,ty,sS; queue<QS> q; int p[21][517619];bool Query(SS a) {int i=a.S%P;for (int j=p[a.u][i];j;j=e[j].nx)if (e[j].v==a.S) return 1;return 0; }void Insert(SS a) {int i=a.S%P;e[++cnt]=(Graph){a.S,p[a.u][i]};p[a.u][i]=cnt; }int Roll(int S,int type) {switch (type) {case 0:return (S&48)|((S&3)<<2)|((S&4)>>1)|((S&8)>>3);case 1:return (S&48)|((S&1)<<3)|((S&2)<<1)|((S&12)>>2);case 2:return ((S&3)<<4)|(S&12)|((S&16)>>3)|((S&32)>>5);case 3:return ((S&1)<<5)|((S&2)<<3)|(S&12)|((S&48)>>4);} }void Solve(int u,int bS,int cS,int dep) {if ((cS&1)^((bS>>u-1)&1)) cS^=1,bS^=(1<<u-1);if (!bS&&u==id[tx][ty]) {printf("%d",dep-1);exit(0);}int S=bS|(cS<<icnt);if (Query((SS){u,S})) return;q.push((QS){(SS){u,S},dep});Insert((SS){u,S}); }void BFS() {q.push((QS){(SS){id[sx][sy],sS},1});Insert((SS){id[sx][sy],sS});while (!q.empty()) {QS a=q.front();q.pop();int u=a.s.u,bS=a.s.S&((1<<icnt)-1),cS=a.s.S>>icnt,dep=a.dep;for (int i=0;i<4;i++)if (g[u][i]) {int scS=Roll(cS,i);Solve(g[u][i],bS,scS,dep+1);}} }int main() {scanf("%d%d",&m,&n);for (int i=1;i<=m;i++) scanf("%s",c[i]+1);for (int i=1;i<=m;i++)for (int j=1;j<=n;j++) {if (c[i][j]!='#') id[i][j]=++icnt;if (c[i][j]=='C') sx=i,sy=j;if (c[i][j]=='G') tx=i,ty=j;if (c[i][j]=='P') sS|=(1<<icnt-1);}for (int i=1;i<=m;i++)for (int j=1;j<=n;j++)if (c[i][j]!='#') {if (i>1&&c[i-1][j]!='#') g[id[i][j]][0]=id[i-1][j];if (i<m&&c[i+1][j]!='#') g[id[i][j]][1]=id[i+1][j];if (j>1&&c[i][j-1]!='#') g[id[i][j]][2]=id[i][j-1];if (j<n&&c[i][j+1]!='#') g[id[i][j]][3]=id[i][j+1];}BFS(); }
View Code
转载于:https://www.cnblogs.com/mastervan/p/11117931.html
[状压DP][BFS][哈希]JZOJ 3243 Cube相关推荐
- HDU - 3247 Resource Archiver(AC自动机+状压dp+bfs)
题目链接:点击查看 题目大意:给出 n 个目标串和 m 个病毒串,要求构造出一个长度最短的,且包含全部 n 个目标串,但是不能包含任意一个病毒串的01字符串,输出其最短长度 题目分析:比较综合的一道题 ...
- 洛谷P2622 关灯问题II【状压dp+bfs】
P2622 关灯问题II 题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯--按下了第i个按钮,对于所有的灯都有一个效果.按下i按钮对于第j盏灯,是下面3中效果之一:如果a[i][j] ...
- Tunnels 状压DP+BFS
Bob is travelling in Xi'an. He finds many secret tunnels beneath the city. In his eyes, the city is ...
- P3118 [USACO15JAN] 状压 DP + BFS
题意 传送门 P3118 [USACO15JAN]Moovie Mooving 题解 爆搜至少 O(N!)O(N!)O(N!),考虑状态压缩 DPDPDP.dp[i]dp[i]dp[i] 代表集合 i ...
- 【状压DP】最优配对问题(jzoj 3420)
最优配对问题 jzoj 3420 题目大意: 在平面上有n个点,现在要把他们拼成n/2对,拼接两个点的代价是他们的平面距离,现在问代价总和最小是多少 输入样例 4 8730 9323 -3374 39 ...
- [2021-09-09 T3] 序列/luogu P3943 星空(异或差分+bfs最短路+状压dp)
序列 description solution code description 题目描述 长度为nnn的序列,初始全为000,每次可以选择⼀个数ai(1≤i≤l)a_i(1\le i\le l)ai ...
- 【状压DP】剑之修炼(jzoj 2130)
剑之修炼 jzoj 2130 题目大意: 在一个位置上有一个人,同时还有NNN(N⩽10N \leqslant 10N⩽10)个怪物,这个人会不停地释放技能,技能可以瞬间杀死周围8个格子上的怪物,行走 ...
- Tunnels HDU - 4856 (bfs状压dp)
Tunnels HDU - 4856 Bob is travelling in Xi'an. He finds many secret tunnels beneath the city. In his ...
- HDU-4856 Tunnels(BFS状压DP)
Tunnels http://acm.hdu.edu.cn/showproblem.php?pid=4856 Time Limit: 3000/1500 MS (Java/Others) Mem ...
最新文章
- python pandas DataFrame 字符串转日期格式
- 在Visual Studio 2010中实现数据驱动Coded UI Tests
- 解决 Mysql下使用EF Code First 指定表Engine无效的思路
- 转sql exists和not exists用法
- Laravel 上传图片及多张图片到七牛云
- centos7中无法确定光盘权限怎么办_图解KVM安装CentOS7.6操作系统
- c++牛客网面试题05. 替换空格
- P1463-[POI2002][HAOI2007]反素数【约数,数论】
- strlen函数strcpy函数strcat函数的实现
- Trie 树内存消耗问题
- api 原生hbase_数据查询的玄铁剑:云HBase原生二级索引发布
- 哎呀,搬运blog好累啊,96篇呢QwQ
- Python 模拟黑客帝国中的“代码雨”
- 德拜方程及matlab实现
- C++ 完全不完全资源导引
- 高效率笔记——5R笔记法(康奈尔笔记法)
- 在matlab设置三角波,matlab 中repeating sequence中怎样设置20khz三角波
- hadoopsnappy解压_配置Hadoop2.7.2和Hbase1.1.5支持Snappy解压压缩库
- Premiere Pro之视频升格降格(六)
- Ceres Solver从零开始手把手教学使用