八数码之双广解决方法
来源:互联网 发布:c语言的发展历程 编辑:程序博客网 时间:2024/04/29 09:09
从起始状态和末尾状态分别进行bfs,每次从队列节点少的队列进行遍历,当两个队列重合的时候就是找到答案的时候。
#include<iostream>using namespace std;#define SWAP(a, b) {char t = a; a = b; b = t;}const int MAXN = 200000;struct Node{ char tile[10]; //数据 int parent; //父节点 int pos; //x的位置 char dir; //方向};Node qu[2][MAXN]; //两个队列int head[2], tail[2]; //两个队列的头和尾int _move[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };char _dir[4][2] = { { 'u', 'd' }, { 'd', 'u' }, { 'l', 'r' }, { 'r', 'l' } };char _start[10], _end[10] = "12345678x";//初始化void init(int qi, const char* state){ strcpy(qu[qi][0].tile, state); qu[qi][0].pos = strchr(state, 'x') - state; qu[qi][0].parent = -1; head[qi] = tail[qi] = 0;}//输入void input(){ for (int i = 0; i < 9; i++){ cin >> _start[i]; } _start[9] = '\0'; init(0, _start); init(1, _end);}//判断是否重复int isVis(int id){ for (int i = 0; i < tail[id]; i++){ if (strcmp(qu[id][i].tile, qu[id][tail[id]].tile) == 0) return 1; } return 0;}//判断是否和另一个队列重合int isResult(int id){ for (int i = 0; i < tail[1-id]; i++){ if (strcmp(qu[1-id][i].tile, qu[id][tail[id]].tile) == 0) return i; } return -1;}void print_backward(int i){ if (qu[0][i].parent != -1) { print_backward(qu[0][i].parent); printf("%c", qu[0][i].dir); }}void print_forward(int j){ if (qu[1][j].parent != -1) { printf("%c", qu[1][j].dir); print_forward(qu[1][j].parent); }}void print_result(int i, int j){ //printf("%d,%d\n", i, j); print_backward(i); print_forward(j); printf("\n");}//广度搜索int bfs(int id){ int r; Node temp,p = qu[id][head[id]++]; for (int i = 0; i < 4; i++){ int x = p.pos / 3 + _move[i][0]; int y = p.pos % 3 + _move[i][1]; if (x < 0 || x >= 3 || y < 0 || y >= 3) continue; strcpy(temp.tile, p.tile); SWAP(temp.tile[p.pos],temp.tile[3*x+y]); temp.parent = head[id] - 1; temp.pos = x * 3 + y; temp.dir = _dir[i][id]; qu[id][++tail[id]] = temp; if (isVis(id)){ //判断是否存在 tail[id]--; } else //判断向队列有重合 { if ((r=isResult(id))!=-1){ if (id){ //在判断 逆 队列时 print_result(r, tail[1]); } else //在判断 顺 队列时 { print_result(tail[0], r); } return 1; } } } return 0;}int solve(){ while (head[0] <= tail[0] && head[1] <= tail[1]) { if (tail[0] - head[0] >= tail[1] - head[1]){ if (bfs(1)) return 1; } else { if (bfs(0)) return 1; } } return 0;}int main(){ input(); if (!solve()){ }}
0 0
- 八数码之双广解决方法
- 八数码之广搜
- hoj 1868 八数码(双广+hash)
- 八数码之A*解决方法
- 双向广搜 八数码
- 八数码(广搜)
- 八数码广搜代码
- 【双向广搜】八数码难题
- hdu 1043 八数码 单向广搜
- poj3131 立体八数码,双向广搜
- c++八数码问题(广搜)
- 小游戏系列算法之五广度优先搜索,双向广搜,八数码,华容道
- 八数码 康托 逆康托 哈希 双解码 双向广搜
- pku 1077 Eight【八数码、广搜、hash判重】
- 八数码 poj 1077 广搜 A* IDA*
- 【双向广搜+逆序数优化】【HDU1043】【八数码】
- POJ 1077 Eight(八数码) 双向广搜
- 人工智能之八数码问题
- iOS制作属于自己的frameWork
- python短域名数据分析框架
- CSS3 入门4
- 计算机网络——3.网络协议工作原理
- C++中const和指针*的组合问题
- 八数码之双广解决方法
- poj 1979 Red and Black
- 蓝桥杯 历届试题 加法变乘法
- 三分之一的程序猿之重新定义“创业”!
- CSS3 入门5
- Android项目实践:黄金报价
- struts2整合hibernate
- stack栈
- CSS3 入门6