POJ 1077 Eight(八数码第四境界|双向广搜+哈希)
2016-01-21 18:46
495 查看
题意:八数码。
思路:这道题用的算法是双向广搜加哈希,因为HDU是多组样例,所以会超时,交的poj。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<ctime>
#define eps 1e-6
#define LL long long
#define pii pair<int, int>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
const int MAXN = 400000;
//const int INF = 0x3f3f3f3f;
short int has[MAXN];
int fac[9] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320};
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, -1, 0, 1};
int last1[MAXN], last2[MAXN];
short int mov1[MAXN], mov2[MAXN];
struct State {
short int s[9];
short int pos;
int hash;
} ini, target;
queue<State> q1, q2;
int Hash(short int* s) {
int res = 0;
for(int i = 0; i < 8; i++) {
int cnt = 0;
for(int j = i + 1; j < 9; j++) {
if(s[i] > s[j]) cnt++;
}
res += cnt * fac[8-i];
}
return res;
}
int cal_pos(int pos, int i) {
int nx = pos/3+dx[i], ny = pos%3+dy[i];
if(nx<0 || nx>2 || ny<0 || ny>2) return -1;
return nx*3 + ny;
}
void DBFS_init() {
while(!q1.empty()) q1.pop();
while(!q2.empty()) q2.pop();
for(int i = 0; i < 9; i++) target.s[i] = i+1;
target.pos = 8;
target.hash = 0;
has[0] = 2;
q2.push(target);
q1.push(ini);
has[ini.hash] = 1;
}
int q1_expand() {
if(q1.empty()) return -1;
State ha = q1.front();
q1.pop();
State tmp;
for(int i = 0; i < 4; i++) {
tmp.pos = cal_pos(ha.pos, i);
if(tmp.pos<0) continue;
for(int j = 0; j < 9; j++) {
if(j==ha.pos) tmp.s[j] = ha.s[tmp.pos];
else if(j == tmp.pos) tmp.s[j] = ha.s[ha.pos];
else tmp.s[j] = ha.s[j];
}
tmp.hash = Hash(tmp.s);
if(has[tmp.hash] == 1) continue;
q1.push(tmp);
last1[tmp.hash] = ha.hash;
mov1[tmp.hash] = i;
if(has[tmp.hash] == 2) return tmp.hash;
has[tmp.hash] = 1;
}
return -1;
}
int q2_expand() {
if(q2.empty()) return -1;
State ha = q2.front();
q2.pop();
State tmp;
for(int i = 0; i < 4; i++) {
tmp.pos = cal_pos(ha.pos, i);
if(tmp.pos<0) continue;
for(int j = 0; j < 9; j++) {
if(j==ha.pos) tmp.s[j] = ha.s[tmp.pos];
else if(j == tmp.pos) tmp.s[j] = ha.s[ha.pos];
else tmp.s[j] = ha.s[j];
}
tmp.hash = Hash(tmp.s);
if(has[tmp.hash] == 2) continue;
q2.push(tmp);
last2[tmp.hash] = ha.hash;
mov2[tmp.hash] = i;
if(has[tmp.hash] == 1) return tmp.hash;
has[tmp.hash] = 2;
}
return -1;
}
int DBFS() {
DBFS_init();
while(!q1.empty() || !q2.empty()) {
int ans1 = q1_expand();
if(ans1 >= 0) return ans1;
int ans2 = q2_expand();
if(ans2 >= 0) return ans2;
}
return -1;
}
void print_path1(int x) {
if(x==ini.hash) return;
print_path1(last1[x]);
int i = mov1[x];
if(!i) printf("u");
else if(i==1) printf("l");
else if(i==2) printf("d");
else printf("r");
}
void print_path2(int x) {
if(x==0) return;
int i = mov2[x];
if(!i) printf("d");
else if(i==1) printf("r");
else if(i==2) printf("u");
else printf("l");
print_path2(last2[x]);
}
int main() {
//freopen("input.txt", "r", stdin);
char tmp;
while(cin >> tmp) {
memset(has, 0, sizeof(has));
if(tmp != 'x') ini.s[0] = tmp - '0';
else {
ini.s[0] = 9;
ini.pos = 0;
}
for(int i = 1; i < 9; i++) {
cin >> tmp;
if(tmp == 'x') {
ini.s[i] = 9;
ini.pos = i;
}
else ini.s[i] = tmp - '0';
}
ini.hash = Hash(ini.s);
int ans = DBFS();
if(ans < 0) printf("unsolvable");
else {
print_path1(ans);
print_path2(ans);
}
puts("");
}
return 0;
}
思路:这道题用的算法是双向广搜加哈希,因为HDU是多组样例,所以会超时,交的poj。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<ctime>
#define eps 1e-6
#define LL long long
#define pii pair<int, int>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
const int MAXN = 400000;
//const int INF = 0x3f3f3f3f;
short int has[MAXN];
int fac[9] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320};
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, -1, 0, 1};
int last1[MAXN], last2[MAXN];
short int mov1[MAXN], mov2[MAXN];
struct State {
short int s[9];
short int pos;
int hash;
} ini, target;
queue<State> q1, q2;
int Hash(short int* s) {
int res = 0;
for(int i = 0; i < 8; i++) {
int cnt = 0;
for(int j = i + 1; j < 9; j++) {
if(s[i] > s[j]) cnt++;
}
res += cnt * fac[8-i];
}
return res;
}
int cal_pos(int pos, int i) {
int nx = pos/3+dx[i], ny = pos%3+dy[i];
if(nx<0 || nx>2 || ny<0 || ny>2) return -1;
return nx*3 + ny;
}
void DBFS_init() {
while(!q1.empty()) q1.pop();
while(!q2.empty()) q2.pop();
for(int i = 0; i < 9; i++) target.s[i] = i+1;
target.pos = 8;
target.hash = 0;
has[0] = 2;
q2.push(target);
q1.push(ini);
has[ini.hash] = 1;
}
int q1_expand() {
if(q1.empty()) return -1;
State ha = q1.front();
q1.pop();
State tmp;
for(int i = 0; i < 4; i++) {
tmp.pos = cal_pos(ha.pos, i);
if(tmp.pos<0) continue;
for(int j = 0; j < 9; j++) {
if(j==ha.pos) tmp.s[j] = ha.s[tmp.pos];
else if(j == tmp.pos) tmp.s[j] = ha.s[ha.pos];
else tmp.s[j] = ha.s[j];
}
tmp.hash = Hash(tmp.s);
if(has[tmp.hash] == 1) continue;
q1.push(tmp);
last1[tmp.hash] = ha.hash;
mov1[tmp.hash] = i;
if(has[tmp.hash] == 2) return tmp.hash;
has[tmp.hash] = 1;
}
return -1;
}
int q2_expand() {
if(q2.empty()) return -1;
State ha = q2.front();
q2.pop();
State tmp;
for(int i = 0; i < 4; i++) {
tmp.pos = cal_pos(ha.pos, i);
if(tmp.pos<0) continue;
for(int j = 0; j < 9; j++) {
if(j==ha.pos) tmp.s[j] = ha.s[tmp.pos];
else if(j == tmp.pos) tmp.s[j] = ha.s[ha.pos];
else tmp.s[j] = ha.s[j];
}
tmp.hash = Hash(tmp.s);
if(has[tmp.hash] == 2) continue;
q2.push(tmp);
last2[tmp.hash] = ha.hash;
mov2[tmp.hash] = i;
if(has[tmp.hash] == 1) return tmp.hash;
has[tmp.hash] = 2;
}
return -1;
}
int DBFS() {
DBFS_init();
while(!q1.empty() || !q2.empty()) {
int ans1 = q1_expand();
if(ans1 >= 0) return ans1;
int ans2 = q2_expand();
if(ans2 >= 0) return ans2;
}
return -1;
}
void print_path1(int x) {
if(x==ini.hash) return;
print_path1(last1[x]);
int i = mov1[x];
if(!i) printf("u");
else if(i==1) printf("l");
else if(i==2) printf("d");
else printf("r");
}
void print_path2(int x) {
if(x==0) return;
int i = mov2[x];
if(!i) printf("d");
else if(i==1) printf("r");
else if(i==2) printf("u");
else printf("l");
print_path2(last2[x]);
}
int main() {
//freopen("input.txt", "r", stdin);
char tmp;
while(cin >> tmp) {
memset(has, 0, sizeof(has));
if(tmp != 'x') ini.s[0] = tmp - '0';
else {
ini.s[0] = 9;
ini.pos = 0;
}
for(int i = 1; i < 9; i++) {
cin >> tmp;
if(tmp == 'x') {
ini.s[i] = 9;
ini.pos = i;
}
else ini.s[i] = tmp - '0';
}
ini.hash = Hash(ini.s);
int ans = DBFS();
if(ans < 0) printf("unsolvable");
else {
print_path1(ans);
print_path2(ans);
}
puts("");
}
return 0;
}
相关文章推荐
- 搜狗百度360市值齐跌:搜索引擎们陷入集体焦虑?
- 本人即将筹备败家日志,敬请期待!
- IE:使用搜索助手
- Mootools 1.2教程 定时器和哈希简介
- C++深度优先搜索的实现方法
- 基于文本的搜索
- php实现搜索一维数组元素并删除二维数组对应元素的方法
- 使用Sphinx对索引进行搜索
- asp 多关键词搜索的简单实现方法
- C#获取哈希加密生成随机安全码的类实例
- C#使用foreach语句搜索数组元素的方法
- WordPress中用于获取搜索表单的PHP函数使用解析
- JavaScript中数组的排序、乱序和搜索实现代码
- C#计算字符串哈希值(MD5、SHA)的方法小结
- C#编程实现Excel文档中搜索文本内容的方法及思路
- sqlserver中在指定数据库的所有表的所有列中搜索给定的值
- 可以用来搜索当前页面内容的js代码
- 全文搜索和替换
- javascript搜索自动提示功能的实现第1/3页
- mysql 模糊搜索的方法介绍