压状态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代表白棋,现在有一种操作,如果你想要改变某一个棋子的颜色,那么它周围(前后左右)棋子的颜色都会被改变(白变成黑,黑变成白),问你将所有棋子变成 ...
随机推荐
- C#自定义事件监视变量变化
首先监视定义类 class Event { public delegate void tempChange(object sender, EventArgs e); public event temp ...
- 事件代理(event的target属性)
event的target属性 一个题:请通过事件代理实现当点击每一个li标签,弹出相应li标签内的内容 Event对象提供了一个属性叫target,可以返回事件的目标节点,我们称为事件源,也就是说,t ...
- ASP.NET WEB API微信支付通知接口,返回xml数据,微信服务器不识别问题
原文:ASP.NET WEB API微信支付通知接口,返回xml数据,微信服务器不识别问题 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/MrTra ...
- HDFS 断点续传,写文件功能
实际上这是个 HDFS 的工具类部分代码. 首先 public static Configuration configuration = null;public static FileSystem f ...
- 【转载】GitHub详细教程
1 Git详细教程 1.1 Git简介 1.1.1 Git是何方神圣? Git是用C语言开发的分布版本控制系统.版本控制系统可以保留一个文件集合的历史记录,并能回滚文件集合到另一个状态(历 ...
- 129.C++面试一百题(1-51)
- 不允许 ASSIGNMENT 语句中包含 FOR XML 子句。
DECLARE @guidList NVARCHAR(max) SELECT @guidList=( CAST(OrderGUID AS nvarchar(max)) +',') FROM Order ...
- cf 864 F. Cities Excursions
F. Cities Excursions There are n cities in Berland. Some pairs of them are connected with m directed ...
- Linux下通过.desktop 文件创建桌面程序图标及文件编写方式(Desktop Entry文件概述)
Linux下通过.desktop 文件创建桌面程序图标及文件编写方式 1.Desktop Entry文件概述:在 Windows 平台上,用户可以通过点击位于桌面或菜单上的快捷方式轻松打开目标应用程序 ...
- dos 实用命令搜集
dos 命令: 1.netstat -an 2.XP下打开凭证管理: control keymgr.dll 3.刷新DHCP协议,重新自动获取IP * ipconfig/release 命令来丢 ...