POJ1077 Eight —— 正向BFS
主页面:http://www.cnblogs.com/DOLFAMINGO/p/7538588.html
代码一:以数组充当队列,利用结构体中的pre追溯上一个状态在数组(队列)中的下标:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 1e6+;
#define AIM 1 //123456789的哈希值为1 struct node
{
int status;
int s[];
int loc;
char path;
int pre; //pre为上一个操作在队列中的下标,用于输出路径
}; int vis[MAXN], fac[] = { , , , , , , , , };
int dir[][] = { -,, ,, ,-, , };
char op[] = {'u', 'd', 'l', 'r' }; int cantor(int s[]) //获得哈希函数值
{
int sum = ;
for(int i = ; i<; i++)
{
int num = ;
for(int j = i+; j<; j++)
if(s[j]<s[i])
num++;
sum += num*fac[-i];
}
return sum+;
} node que[MAXN];
int front, rear;
int bfs(node now)
{
ms(vis,);
front = rear = ; now.status = cantor(now.s);
vis[now.status] = ;
que[rear++] = now; node tmp;
while(front!=rear)
{
now = que[front++];
if(now.status==AIM)
return front-; int x = now.loc/;
int y = now.loc%;
for(int i = ; i<; i++)
{
int xx = x + dir[i][];
int yy = y + dir[i][];
if(xx>= && xx<= && yy>= && yy<=)
{
tmp = now;
tmp.s[x*+y] = tmp.s[xx*+yy]; //交换位置,下同
tmp.s[xx*+yy] = ;
tmp.status = cantor(tmp.s);
if(!vis[tmp.status])
{
vis[tmp.status] = ;
tmp.loc = xx*+yy;
tmp.path = op[i]; //保存操作
tmp.pre = front-; //保存当前结点的状态的上一个状态所在的结点在数组(队列)的下标
que[rear++] = tmp;
}
}
}
}
return -;
} void Print(int i) //利用递归的特点(压栈),输出路径
{
if(i==) return; //到了目的状态,则退出。目的状态的结点在数组(队列)中的下标为0
Print(que[i].pre); //访问上一步
putchar(que[i].path); //输出操作
} int main()
{
char tmp[];
while(gets(tmp))
{
node beg;
int cnt = ;
for(int i = ; tmp[i]; i++)
{
if(tmp[i]==' ') continue;
if(tmp[i]=='x') beg.s[cnt] = , beg.loc = cnt++;
else beg.s[cnt++] = tmp[i]-''; }
int i = bfs(beg);
if(i==-)
puts("unsolvable");
else
Print(i), putchar('\n');
}
}
代码二(推荐):把pre和path放在结构体外,利用当前状态status追溯上一个状态status:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 1e6+;
#define AIM 1 //123456789的哈希值为1 struct node
{
int status;
int s[];
int loc;
}; int vis[MAXN], fac[] = { , , , , , , , , };
int dir[][] = { -,, ,, ,-, , };
char op[] = {'u', 'd', 'l', 'r' };
char path[MAXN];
int pre[MAXN]; int cantor(int s[]) //获得哈希函数值
{
int sum = ;
for(int i = ; i<; i++)
{
int num = ;
for(int j = i+; j<; j++)
if(s[j]<s[i])
num++;
sum += num*fac[-i];
}
return sum+;
} queue<node>que;
bool bfs(node now)
{
ms(vis,);
while(!que.empty()) que.pop(); now.status = cantor(now.s);
pre[now.status] = -; //开始状态的上一个状态为-1,用于输出路径时“刹车”
vis[now.status] = ;
que.push(now); node tmp;
while(!que.empty())
{
now = que.front();
que.pop();
if(now.status==AIM) //找到了123456789的状态
return true; int x = now.loc/;
int y = now.loc%;
for(int i = ; i<; i++)
{
int xx = x + dir[i][];
int yy = y + dir[i][];
if(xx>= && xx<= && yy>= && yy<=)
{
tmp = now;
tmp.s[x*+y] = tmp.s[xx*+yy]; //交换位置,下同
tmp.s[xx*+yy] = ;
tmp.status = cantor(tmp.s);
if(!vis[tmp.status])
{
vis[tmp.status] = ;
tmp.loc = xx*+yy;
pre[tmp.status] = now.status; //tmp.status的上一个状态为now.status
path[tmp.status] = op[i]; //保存操作
que.push(tmp);
}
}
}
}
return ;
} void Print(int status)
{
if(pre[status]==-) return;
Print(pre[status]); //追溯上一个状态
putchar(path[status]);
} int main()
{
char str[];
while(gets(str))
{
node now;
int cnt = ;
for(int i = ; str[i]; i++)
{
if(str[i]==' ') continue;
if(str[i]=='x') now.s[cnt] = , now.loc = cnt++;
else now.s[cnt++] = str[i]-'';
}
if(!bfs(now))
puts("unsolvable");
else
Print(AIM), putchar('\n');
}
}
POJ1077 Eight —— 正向BFS的更多相关文章
- poj1077(康托展开+bfs+记忆路径)
题意:就是说,给出一个三行三列的数组,其中元素为1--8和x,例如: 1 2 3 现在,需要你把它变成:1 2 3 要的最少步数的移动方案.可以右移r,左移l,上移u,下移dx 4 6 4 5 67 ...
- POJ1077 八数码 BFS
BFS 几天的超时... A*算法不会,哪天再看去了. /* 倒搜超时, 改成顺序搜超时 然后把记录路径改成只记录当前点的操作,把上次的位置记录下AC..不完整的人生啊 */ #include < ...
- POJ1077 Eight —— 双向BFS
主页面:http://www.cnblogs.com/DOLFAMINGO/p/7538588.html (代码一直在精简完善……) 代码一:两个BFS, 两段代码: 用step控制“你一步, 我一步 ...
- POJ1077 Eight —— 反向BFS
主页面:http://www.cnblogs.com/DOLFAMINGO/p/7538588.html 代码一:以数组充当队列,利用结构体中的pre追溯上一个状态在数组(队列)中的下标: #incl ...
- POJ1077 Eight —— 经典的搜索问题
题目链接:http://poj.org/problem?id=1077 Eight Time Limit: 1000MS Memory Limit: 65536K Total Submission ...
- 逆向+两次bfs(UVA 1599)
为什么都说简单好想咧.坦白从宽看了人家的代码,涨了好多姿势,, http://blog.csdn.net/u013382399/article/details/38227917 被一个细节坑了.. 2 ...
- 双向BFS—>NOIP2002 字串变换
如果目标也已知的话,用双向BFS能很大提高速度 单向时,是 b^len的扩展. 双向的话,2*b^(len/2) 快了很多,特别是分支因子b较大时 至于实现上,网上有些做法是用两个队列,交替节点搜索 ...
- BFS && DFS
HDOJ 1312 Red and Black http://acm.hdu.edu.cn/showproblem.php?pid=1312 很裸的dfs,在dfs里面写上ans++,能到几个点就调了 ...
- UVa1599 Ideal Path(双向bfs+字典序+非简单图的最短路+队列判重)
题目大意: 对于一个n个房间m条路径的迷宫(Labyrinth)(2<=n<=100000, 1<=m<=200000),每条路径上都涂有颜色,颜色取值范围为1<=c&l ...
随机推荐
- charts 画饼图
统计某一天某类物体的百分比 新知识点:aggregate https://blog.csdn.net/congcong68/article/details/51619882 主要的 $group $m ...
- Linux(12):期中架构(4)--- 前端部分:HTTP & Nginx & LNMP架构
HTTP协议概念原理说明 1. 当用户访问一个网站时经历的过程 # ①. 利用DNS服务,将输入的域名解析为相应的IP地址 a 本地主机输入域名后,会查询本地缓存信息和本地hosts b 本地主机会向 ...
- Codeforces983D. Arkady and Rectangles
$n \leq 100000$个矩形,一个一个覆盖在坐标系上,每个颜色都不一样,问最后能看到几种颜色. 由于后面的颜色可以覆盖前面的颜色,可以把颜色与时间联系上,第$i$个矩形颜色$i$来把时间维变成 ...
- Linux性能分析Top
前言 在实际开发中,有时候会收到一些服务的监控报警,比如CPU飙高,内存飙高等,这个时候,我们会登录到服务器上进行排查.本篇博客将涵盖这方面的知识:Linux性能工具. 一次线上问题排查模拟 背景:服 ...
- 每日记录 2016-4-29 HTML5本地存储
HTML5本地存储 一.HTML5 localStorage 在HTML5中,本地存储是一个window的属性,包括localStorage和 sessionStorage,从名字应该可以很清楚的辨认 ...
- ubuntu下安装翻译软件
原文: http://sixipiaoyang.blog.163.com/blog/static/6232358820144146386437/ Ubuntu下常用的翻译软件有StarDict,Gol ...
- Codeforces Gym 100286I iSharp 模拟
原题地址:http://codeforces.com/gym/100286/attachments/download/2013/20082009-acmicpc-northeastern-europe ...
- Proximal Gradient Descent for L1 Regularization(近端梯度下降求解L1正则化问题)
假设我们要求解以下的最小化问题: $min_xf(x)$ 如果$f(x)$可导,那么一个简单的方法是使用Gradient Descent (GD)方法,也即使用以下的式子进行迭代求解: $x_{k+1 ...
- Codeforces Round #266 (Div. 2) C. Number of Ways
You've got array a[1], a[2], ..., a[n], consisting of n integers. Count the number of ways to split ...
- TListView使用方法1(转)
ListView1.Items 为标准 Tlistitems类 ListView1.Items (1)赋值 with ListView1.Items.Add do begin Caption:=cap ...