POJ1077 Eight —— 正向BFS
来源:互联网 发布:淘宝直通车没有展现量 编辑:程序博客网 时间:2024/05/19 06:16
主页面:http://blog.csdn.net/dolfamingo/article/details/77825569
代码一:以数组充当队列,利用结构体中的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+7;const int MAXN = 1e6+10;#define AIM 1 //123456789的哈希值为1struct node{ int status; int s[9]; int loc; char path; int pre; //pre为上一个操作在队列中的下标,用于输出路径};int vis[MAXN], fac[9] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320};int dir[4][2] = { -1,0, 1,0, 0,-1, 0,1 };char op[4] = {'u', 'd', 'l', 'r' };int cantor(int s[]) //获得哈希函数值{ int sum = 0; for(int i = 0; i<9; i++) { int num = 0; for(int j = i+1; j<9; j++) if(s[j]<s[i]) num++; sum += num*fac[8-i]; } return sum+1;}node que[MAXN];int front, rear;int bfs(node now){ ms(vis,0); front = rear = 0; now.status = cantor(now.s); vis[now.status] = 1; que[rear++] = now; node tmp; while(front!=rear) { now = que[front++]; if(now.status==AIM) return front-1; int x = now.loc/3; int y = now.loc%3; for(int i = 0; i<4; i++) { int xx = x + dir[i][0]; int yy = y + dir[i][1]; if(xx>=0 && xx<=2 && yy>=0 && yy<=2) { tmp = now; tmp.s[x*3+y] = tmp.s[xx*3+yy]; //交换位置,下同 tmp.s[xx*3+yy] = 9; tmp.status = cantor(tmp.s); if(!vis[tmp.status]) { vis[tmp.status] = 1; tmp.loc = xx*3+yy; tmp.path = op[i]; //保存操作 tmp.pre = front-1; //保存当前结点的状态的上一个状态所在的结点在数组(队列)的下标 que[rear++] = tmp; } } } } return -1;}void Print(int i) //利用递归的特点(压栈),输出路径{ if(i==0) return; //到了目的状态,则退出。目的状态的结点在数组(队列)中的下标为0 Print(que[i].pre); //访问上一步 putchar(que[i].path); //输出操作}int main(){ char tmp[50]; while(gets(tmp)) { node beg; int cnt = 0; for(int i = 0; tmp[i]; i++) { if(tmp[i]==' ') continue; if(tmp[i]=='x') beg.s[cnt] = 9, beg.loc = cnt++; else beg.s[cnt++] = tmp[i]-'0'; } int i = bfs(beg); if(i==-1) 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+7;const int MAXN = 1e6+10;#define AIM 1 //123456789的哈希值为1struct node{ int status; int s[9]; int loc;};int vis[MAXN], fac[9] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320};int dir[4][2] = { -1,0, 1,0, 0,-1, 0,1 };char op[4] = {'u', 'd', 'l', 'r' };char path[MAXN];int pre[MAXN];int cantor(int s[]) //获得哈希函数值{ int sum = 0; for(int i = 0; i<9; i++) { int num = 0; for(int j = i+1; j<9; j++) if(s[j]<s[i]) num++; sum += num*fac[8-i]; } return sum+1;}queue<node>que;bool bfs(node now){ ms(vis,0); while(!que.empty()) que.pop(); now.status = cantor(now.s); pre[now.status] = -1; //开始状态的上一个状态为-1,用于输出路径时“刹车” vis[now.status] = 1; que.push(now); node tmp; while(!que.empty()) { now = que.front(); que.pop(); if(now.status==AIM) //找到了123456789的状态 return true; int x = now.loc/3; int y = now.loc%3; for(int i = 0; i<4; i++) { int xx = x + dir[i][0]; int yy = y + dir[i][1]; if(xx>=0 && xx<=2 && yy>=0 && yy<=2) { tmp = now; tmp.s[x*3+y] = tmp.s[xx*3+yy]; //交换位置,下同 tmp.s[xx*3+yy] = 9; tmp.status = cantor(tmp.s); if(!vis[tmp.status]) { vis[tmp.status] = 1; tmp.loc = xx*3+yy; pre[tmp.status] = now.status; //tmp.status的上一个状态为now.status path[tmp.status] = op[i]; //保存操作 que.push(tmp); } } } } return 0;}void Print(int status){ if(pre[status]==-1) return; Print(pre[status]); //追溯上一个状态 putchar(path[status]);}int main(){ char str[50]; while(gets(str)) { node now; int cnt = 0; for(int i = 0; str[i]; i++) { if(str[i]==' ') continue; if(str[i]=='x') now.s[cnt] = 9, now.loc = cnt++; else now.s[cnt++] = str[i]-'0'; } if(!bfs(now)) puts("unsolvable"); else Print(AIM), putchar('\n'); }}
阅读全文
0 0
- poj1077 Eight —— 正向bfs+康拓
- POJ1077 Eight —— 正向BFS
- POJ1077 Eight —— 反向BFS
- POJ1077 Eight —— 双向BFS
- POJ1077——Eight
- POJ1077 Eight —— A*算法
- POJ1077 Eight —— IDA*算法
- POJ1077 Eight —— 经典的搜索问题
- poj1077 Eight
- POJ1077、HDU1043 Eight 八数码问题:双向BFS、A*
- 【康托展开+状压BFS】poj1077 Eight(八数码问题)
- poj1077 /hdoj 1043 Eight
- 【POJ1077】Eight【IDA*】
- hdu1043 Eight —— 反向bfs+康拓
- POJ 1077 Eight (正向BFS + 康托展开)
- Eight poj1077 广度优先搜索
- poj1077 hdu1043 Eight 八数码问题
- 八数码 poj1077 Eight(A*、IDA*)
- NYOJ 329 循环小数
- 数学建模(10)——支持向量机的MATLAB应用
- BZOJ 3555: [Ctsc2014]企鹅QQ 哈希
- HDU 6187 Destroy Walls(最大生成树)
- 结构型设计模式
- POJ1077 Eight —— 正向BFS
- Root of AVL Tree
- Codeforces Round #432 (Div. 2) 题解
- Markdown语法入门
- WOJ1173-Josephus Permutation
- hash算法原理详解
- 老三长谈之Retrofit源码分析
- springmvc自定义拦截器配置和使用
- Spring 定时任务之 @Scheduled cron表达式