题目传送门1 2

题意:从无序到有序移动的方案,即最后成1 2 3 4 5 6 7 8 0

分析:八数码经典问题。POJ是一次,HDOJ是多次。因为康托展开还不会,也写不了什么,HDOJ需要从最后的状态逆向搜索,这样才不会超时。判重康托展开,哈希也可。

POJ

//#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<stack>
#include<queue>
#include <cstring>
#include<map>
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<time.h>
#include<math.h>
using namespace std; const int N = 362880 + 5;
const int MOD = 1e6 + 7;
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
char dir[4] = {'u', 'd', 'l', 'r'};
struct Point {
int s, d;
string str;
Point () {}
Point (int s, int d, string str) : s (s), d (d), str (str) {}
};
struct Hash_table {
struct Edge {
int v, nex;
}edge[MOD];
int head[MOD], e;
void init(void) {
memset (head, -1, sizeof (head));
e = 0;
}
bool insert(int x) {
int u = (x % MOD + MOD) % MOD;
for (int i=head[u]; ~i; i=edge[i].nex) {
if (edge[i].v == x) return false;
}
edge[e].v = x; edge[e].nex = head[u];
head[u] = e++;
return true;
}
}ha;
int vis[N], fact[9]; void decode(int x, int *b) {
for (int i=8; i>=0; --i) {
b[i] = x % 10;
x /= 10;
}
} int encode(int *b) {
int ret = 0;
for (int i=0; i<9; ++i) {
ret = ret * 10 + b[i];
}
return ret;
} int find_0(int *b) {
for (int i=0; i<9; ++i) {
if (b[i] == 0) return i;
}
return -1;
} bool check(int x, int y) {
if (x < 0 || x >= 3 || y < 0 || y >= 3) return false;
else return true;
} void print(int *b) {
for (int i=0; i<9; ++i) {
printf ("%d ", b[i]);
if (i == 2 || i == 5 || i == 8) puts ("");
}
} void init(void) {
fact[0] = 1;
for (int i=1; i<9; ++i) fact[i] = fact[i-1] * i;
memset (vis, false, sizeof (vis));
} bool can_insert(int *b) {
int code = 0;
for (int i=0; i<9; ++i) {
int cnt = 0;
for (int j=i+1; j<9; ++j) if (b[j] < b[i]) cnt++;
code += fact[8-i] * cnt;
}
if (vis[code]) return false;
else {
vis[code] = true;
return true;
}
} void BFS(int *a) {
init ();
int ans[9] = {1, 2, 3, 4, 5, 6, 7, 8, 0};
int s = encode (a);
queue<Point> que; que.push (Point (s, 0, ""));
while (!que.empty ()) {
Point u = que.front (); que.pop ();
int b[9];
decode (u.s, b);
if (memcmp (ans, b, sizeof (b)) == 0) {
int len = u.str.length ();
for (int i=0; i<len; ++i) {
printf ("%c", u.str[i]);
}
puts ("");
return ;
}
int p = find_0 (b);
int x = p / 3, y = p % 3;
for (int i=0; i<4; ++i) {
int tx = x + dx[i], ty = y + dy[i];
if (!check (tx, ty)) continue;
int p2 = tx * 3 + ty;
int t[9];
memcpy (t, b, sizeof (b));
t[p] = t[p2]; t[p2] = 0;
int v = encode (t);
//if (!ha.insert (v)) continue;
if (!can_insert (t)) continue;
que.push (Point (v, u.d + 1, u.str + dir[i]));
}
}
puts ("unsolvable");
} int main(void) {
char c[9];
int a[9];
while (scanf ("%c %c %c %c %c %c %c %c %c", &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8]) == 9) {
for (int i=0; i<9; ++i) {
if (c[i] >= '1' && c[i] <= '9') {
a[i] = c[i] - '0';
}
else a[i] = 0;
}
BFS (a);
} return 0;
}

  

HDOJ

#include <bits/stdc++.h>
using namespace std; const int N = 362880 + 5;
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
char dir[4] = {'d', 'u', 'r', 'l'};
struct Point {
int s;
int b[9];
};
struct Ans {
char dir;
int fa;
}ans[N];
int fact[9]; int find_0(int *b) {
for (int i=0; i<9; ++i) {
if (b[i] == 9) return i;
}
return -1;
} bool check(int x, int y) {
if (x < 0 || x >= 3 || y < 0 || y >= 3) return false;
else return true;
} void init(void) {
fact[0] = 1;
for (int i=1; i<9; ++i) fact[i] = fact[i-1] * i;
for (int i=0; i<N; ++i) ans[i].fa = -1;
} int Cantor(int *b) {
int code = 0;
for (int i=0; i<9; ++i) {
int cnt = 0;
for (int j=i+1; j<9; ++j) if (b[j] < b[i]) cnt++;
code += fact[8-i] * cnt;
}
return code;
} void BFS() {
init ();
Point sta;
for (int i=0; i<9; ++i) {
sta.b[i] = i + 1;
}
sta.s = 0; ans[sta.s].fa = 0;
queue<Point> que; que.push (sta);
while (!que.empty ()) {
Point u = que.front (); que.pop ();
int p = find_0 (u.b);
int x = p / 3, y = p % 3;
for (int i=0; i<4; ++i) {
Point v = u;
int tx = x + dx[i], ty = y + dy[i];
if (!check (tx, ty)) continue;
int p2 = tx * 3 + ty;
swap (v.b[p], v.b[p2]);
v.s = Cantor (v.b);
if (ans[v.s].fa != -1) continue;
ans[v.s].dir = dir[i];
ans[v.s].fa = u.s;
que.push (v);
}
}
} int main(void) {
BFS ();
char c[55];
int a[9];
while (gets (c)) {
int j = 0;
for (int i=0; c[i]; ++i) {
if (c[i] >= '0' && c[i] <= '8') {
a[j++] = c[i] - '0';
}
else if (c[i] == 'x') a[j++] = 9;
}
int s = Cantor (a);
if (ans[s].fa == -1) puts ("unsolvable");
else {
while (s != 0) {
printf ("%c", ans[s].dir);
s = ans[s].fa;
}
puts ("");
}
} return 0;
}

  

BFS(八数码) POJ 1077 || HDOJ 1043 Eight的更多相关文章

  1. Eight POJ - 1077 HDU - 1043 八数码

    Eight POJ - 1077 HDU - 1043 八数码问题.用hash(康托展开)判重 bfs(TLE) #include<cstdio> #include<iostream ...

  2. POJ 1077 && HDU 1043 Eight A*算法,bfs,康托展开,hash 难度:3

    http://poj.org/problem?id=1077 http://acm.hdu.edu.cn/showproblem.php?pid=1043 X=a[n]*(n-1)!+a[n-1]*( ...

  3. POJ 1077 HDU 1043 Eight (IDA*)

    题意就不用再说明了吧......如此经典 之前想用双向广搜.a*来写,但总觉得无力,现在用IDA*感觉其他的解法都弱爆了..............想法活跃,时间,空间消耗很小,给它跪了 启发式搜索关 ...

  4. Poj 1077 eight(BFS+全序列Hash解八数码问题)

    一.题意 经典的八数码问题,有人说不做此题人生不完整,哈哈.给出一个含数字1~8和字母x的3 * 3矩阵,如: 1  2  X            3 4  6            7  5  8 ...

  5. hdu 1043 pku poj 1077 Eight (BFS + 康拓展开)

    http://acm.hdu.edu.cn/showproblem.php?pid=1043 http://poj.org/problem?id=1077 Eight Time Limit: 1000 ...

  6. poj 1077 Eight (八数码问题——A*+cantor展开+奇偶剪枝)

    题目来源: http://poj.org/problem?id=1077 题目大意: 给你一个由1到8和x组成的3*3矩阵,x每次可以上下左右四个方向交换.求一条路径,得到12345678x这样的矩阵 ...

  7. HDU 1043 & POJ 1077 Eight(康托展开+BFS+预处理)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30176   Accepted: 13119   Special ...

  8. HDU 1043 Eight (BFS&#183;八数码&#183;康托展开)

    题意  输出八数码问题从给定状态到12345678x的路径 用康托展开将排列相应为整数  即这个排列在全部排列中的字典序  然后就是基础的BFS了 #include <bits/stdc++.h ...

  9. HDU 1043 & POJ 1077 Eight(康托展开+BFS | IDA*)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30176   Accepted: 13119   Special ...

随机推荐

  1. [Android Pro] Toolbar的完全自定义

    reference to : http://blog.csdn.net/elder_sword/article/details/46634751 Toolbar是什么,不知道的可以去大神的博客瞻仰下 ...

  2. August 13th 2016 Week 33rd Saturday

    What makes life dreary is the want of motive. 没有目标与动力,生活便会郁闷无光. Without dreams and hope, there will ...

  3. Mysql undo与redo Log

    http://mysql.taobao.org/monthly/2015/04/01/ http://www.cnblogs.com/Bozh/archive/2013/03/18/2966494.h ...

  4. hdu 5585 Numbers

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5585 思路:对于2和5只须看最后一位数,对于三看所有位的数字之和就行 #include<stdi ...

  5. git 提交代码的流程

    [root@ok-T IT-DOC]# ls hx-海星-wifi.rd web收藏.txt [root@ok-T IT-DOC]# git status -s ?? "web\346\22 ...

  6. 端口扫描之王-----------nmap

    [root@ok data]# nmap -F -sT -v nmap.org Starting Nmap 5.51 ( http://nmap.org ) at 2016-10-23 12:46 C ...

  7. jQuery - 4.简单选择器

    4.1 简单选择器   (1) :first 选取第一个元素.   (2) :last 选取最后一个元素.  (3) :not(选择器) 选取不满足"选择器"条件的元素   (4) ...

  8. 理解理解python中的'*','*args','**','**kwargs'

    http://blog.csdn.net/callinglove/article/details/45483097 讲了一大堆, 我也是用来理解类继承当中的参数行为的. =============== ...

  9. Myeclipse的web工程和Eclipse互相转换

    eclipse的web工程转myeclipse的web工程1.原eclipse工程叫netschool 2.在myeclipse中新建一个工程叫netschool 并在新建的时修改 web root ...

  10. phpcms v9 wap内容页内容显示方法

    phpcms v9的wap手机门户的问题解决 默认的{$content}标签假如内容页一开始输入的不是html代码的话会出现调用不出来的情况,这里用{$rs['content']} 来调用则可以解决问 ...