压状态bfs
一般地图很小,状态不多,可以装压或者hash,构造压缩或hash的函数,构造还原地图的函数,然后就无脑bfs(感觉就是SPFA)
题目:
1.玩具游戏:二进制压缩状态
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
int s,e;
bool vis[1<<17];
int dis[1<<17],map[5][5];
int dy[4]={0,0,1,-1};
int dx[4]={1,-1,0,0};
inline void div(int x){
for(int i=4;i>=1;--i){
for(int j=4;j>=1;--j){
map[i][j]=x&1;
x>>=1;
}
}
}
inline int zip(){
int x=0;
for(int i=1;i<=4;++i){
for(int j=1;j<=4;++j){
x<<=1;
x|=map[i][j];
}
}
return x;
}
inline void bfs(){
queue<int>q;
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
vis[s]=1;
q.push(s);
while(!q.empty()){
int x=q.front();
q.pop();
vis[x]=0;
div(x);
for(int i=1;i<=4;++i){
for(int j=1;j<=4;++j){
if(map[i][j]!=1)continue;
for(int k=0;k<4;++k){
int xx=dx[k]+i;
int yy=dy[k]+j;
if(xx<1||xx>4||yy<1||yy>4)continue;
if(map[xx][yy])continue;
swap(map[xx][yy],map[i][j]);
int w=zip();
swap(map[xx][yy],map[i][j]);
if(dis[w]>dis[x]+1){
dis[w]=dis[x]+1;
if(!vis[w]){
q.push(w);
vis[w]=1;
}
}
}
}
}
}
}
int main(){
for(int i=1;i<=4;++i){
char t[10];
scanf("%s",t+1);
for(int j=1;j<=4;++j){
s<<=1;
if(t[j]=='1')s|=1;
}
}
for(int i=1;i<=4;++i){
char t[10];
scanf("%s",t+1);
for(int j=1;j<=4;++j){
e<<=1;
if(t[j]=='1')e|=1;
}
}
bfs();
cout<<dis[e]<<endl;
return 0;
}
2.八数码难题:偷懒 map来hash存状态,转移很少9!
#include<cstdio>
#include<cstring>
#include<iostream>
#include<map>
#include<queue>
using namespace std;
long long s,t;
int tot,dis[402880],m[4][4];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
map<long long ,int >h;
bool v[20],vis[400000];
inline long long poww(long long a,long long b){
long long ans=1;
while(b){
if(b&1)ans*=a;
a*=a;
b>>=1;
}
return ans;
}
inline void dfs(int pos,long long val){
if(pos>9){
h[val]=++tot;
return ;
}
for(int i=0;i<=8;++i){
if(v[i])continue;
v[i]=1;
dfs(pos+1,val+i*poww(10,pos-1));
v[i]=0;
}
}
inline void div(long long x){
for(int i=3;i>=1;--i){
for(int j=3;j>=1;--j){
m[i][j]=x%10;
x/=10;
}
}
}
inline long long zip(){
long long x=0;
for(int i=1;i<=3;++i){
for(int j=1;j<=3;++j){
x*=10;
x+=m[i][j];
}
}
return x+1000000000;
}
inline void bfs(){
queue<long long>q;
memset(dis,0x3f,sizeof(dis));
int ss=h[s];
vis[ss]=1;
dis[ss]=0;
q.push(s);
while(q.size()){
long long x=q.front();
q.pop();
vis[h[x]]=0;
div(x);
for(int i=1;i<=3;++i){
for(int j=1;j<=3;++j){
if(m[i][j])continue;
for(int k=0;k<4;++k){
int xx=dx[k]+i;
int yy=dy[k]+j;
if(xx<1||xx>3||yy<1||yy>3)continue;
if(!m[xx][yy])continue;
swap(m[xx][yy],m[i][j]);
long long temp=zip();
swap(m[xx][yy],m[i][j]);
int u=h[x];
int v=h[temp];
if(dis[v]>dis[u]+1){
dis[v]=dis[u]+1;
if(!vis[v]){
vis[v]=1;
q.push(temp);
}
}
}
}
}
}
}
int main(){
dfs(1,1000000000);
cin>>s;
s+=1000000000;
t=1123804765;
bfs();
cout<<dis[h[t]];
return 0;
}
压状态bfs的更多相关文章
- hdu 3247 AC自动+状压dp+bfs处理
Resource Archiver Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Ot ...
- BZOJ_3049_[Usaco2013 Jan]Island Travels _状压DP+BFS
BZOJ_3049_[Usaco2013 Jan]Island Travels _状压DP+BFS Description Farmer John has taken the cows to a va ...
- UVA1600 状态BFS
刚开是我用了一种很笨的bfs过掉的,后来看到原来还可以三维带状态BFS,觉得是一个不错的思路. d[x][y][k]表示坐标位于(x,y)经过K个障碍到达时的最短路径,当然如果(x,y)处的数字是0就 ...
- POJ - 2965 The Pilots Brothers' refrigerator(压位+bfs)
The game “The Pilots Brothers: following the stripy elephant” has a quest where a player needs to op ...
- 【状压+状态转移】A Famous Airport Managere
https://www.bnuoj.com/v3/problem_show.php?pid=25653 [题意] 给定一个3*3的九宫格,模拟一个停机坪.第一个格子一定是'*',代表take off ...
- HDU 3681 Prison Break(状压DP + BFS)题解
题意:一张图,F是起点,Y是必须要到的点,D不能走,G可以充电.可以往四个方向走,每走一步花费一个电,走到G可以选择充满电或者不充,每个G只能充一次.问你走遍Y的最小初始点亮.number(G) + ...
- HDU 2209 翻纸牌游戏 状态BFS
翻纸牌游戏 Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem De ...
- 搜索(另类状态BFS):NOIP 华容道
描述 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面,华容道是否根本就无法完成,如果能完成,最少需要多少时间. 小 B 玩的华容道与经典的 ...
- poj1753(位运算压缩状态+bfs)
题意:有个4*4的棋盘,上面摆着黑棋和白旗,b代表黑棋,w代表白棋,现在有一种操作,如果你想要改变某一个棋子的颜色,那么它周围(前后左右)棋子的颜色都会被改变(白变成黑,黑变成白),问你将所有棋子变成 ...
随机推荐
- AIX系统谨慎使用reboot命令
在客户一次停机维护中,发现了这个问题. 环境是ORACLE 10G RAC for AIX6,使用了HACMP管理共享磁盘. 在停机维护时间段内需要重启主机,当关闭了数据库和CLUSTER后,节点1使 ...
- SPFA的小优化
标签:闲扯 SPFA的小优化 1. 向队尾加入元素时,如果它比对首还优,就把把它直接和队首交换. 拿一个双端队列来实现 (手写 , head ,tail STLdeque亲测及其慢) 这个小优化其 ...
- 前端之CSS属性相关
宽和高 width属性可以为元素设置宽度. height属性可以为元素设置高度. 块级标签才能设置宽度,内联标签的宽度由内容来决定. 字体属性 文字字体 font-family可以把多个字体名称作为一 ...
- 紫书 例题 10-6 UVa 1635 (二项式定理+唯一分解定理)
首先可以发现按照题目的算法最后得出来是一个杨辉三角 如果ai的系数是m的倍数,那么i即为答案 因为这个系数可能很大,而我们只需要判断倍数 所以我们就把m分解质因数,然后判断每一个系数 的质因数的幂是不 ...
- 紫书 例题 10-18 UVa 11346(连续概率)
就是面积计算,没什么好说的. #include<cstdio> #include<cmath> #define REP(i, a, b) for(int i = (a); i ...
- [Recompose] Create Stream Behaviors to Push Props in React Components with mapPropsStream
Rather than using Components to push streams into other Components, mapPropsStream allows you to cre ...
- linux 下的select函数
函数原型 /* According to POSIX.1-2001 */ #include <sys/select.h> //头文件 /* According to earlier st ...
- DDR工作原理
DDR SDRAM全称为Double Data Rate SDRAM,中文名为“双倍数据流SDRAM”.DDR SDRAM在原有的SDRAM的基础上改进而来.也正因为如此,DDR能够凭借着转产成本优势 ...
- Android View体系(九)自定义View
相关文章 Android View体系(一)视图坐标系 Android View体系(二)实现View滑动的六种方法 Android View体系(三)属性动画 Android View体系(四)从源 ...
- 24. 在IDEA中使用JUnit进行方法测试
转自:https://blog.csdn.net/smxjant/article/details/78206279 1. 前文 刚学习到的新技能,对JUnit的了解也还是皮毛程度,在这里做个笔记.如果 ...