这道题目最开始做的时候wa+TLE。后面知道需要状态压缩,最近A掉。并且练习一下各种搜索算法。

1. 逆向BFS+康拓展开。

 #include <iostream>
#include <queue>
#include <cstring>
#include <string>
#include <cstdio>
using namespace std; #define N 9
#define MAXNUM 362880 typedef struct {
char map[N];
int xpos;
string path;
} node_st; int fact[N] = {,,,,,,,,};
int direct[][] = {{-,},{,},{,-},{,}};
char rmove[] = {'d','u','r','l'};
char visit[MAXNUM];
string rpath[MAXNUM]; int cantor(node_st node) {
int i, j, cnt, val = ; for (i=; i<N; ++i) {
cnt = ;
for (j=i+; j<N; ++j) {
if (node.map[j] < node.map[i])
++cnt;
}
val += fact[N--i]*cnt;
} return val;
} void bfs() {
queue<node_st> que;
node_st node;
int i, x, y, t1, t2, can; for (i=; i<N; ++i)
node.map[i-] = '' + i;
node.map[N-] = 'x';
node.xpos = N-;
memset(visit, , sizeof(visit));
visit[] = ;
que.push(node); while ( !que.empty() ) {
node = que.front();
que.pop();
t1 = node.xpos / ;
t2 = node.xpos % ;
for (i=; i<; ++i) {
x = t1 + direct[i][];
y = t2 + direct[i][];
if (x< || x>= || y< || y>=)
continue;
node_st tmp(node);
tmp.xpos = x*+y;
tmp.map[node.xpos] = node.map[tmp.xpos];
tmp.map[tmp.xpos] = 'x';
can = cantor(tmp);
if ( !visit[can] ) {
visit[can] = ;
tmp.path += rmove[i];
rpath[can] = tmp.path;
que.push(tmp);
}
}
}
} int main() {
node_st node;
int i, can; bfs(); while (scanf("%c%*c", &node.map[]) != EOF) {
for (i=; i<N; ++i)
scanf("%c%*c", &node.map[i]);
can = cantor(node);
if ( visit[can] ) {
for (i=rpath[can].size()-; i>=; --i)
printf("%c", rpath[can][i]);
printf("\n");
} else {
printf("unsolvable\n");
}
} return ;
}

2. 双端BFS。注意逆序奇偶性相同才有解。

 #include <iostream>
#include <queue>
#include <string>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std; #define N 9
#define MAXNUM 362880 typedef struct {
char map[N];
int xpos;
string path;
} node_st; int fact[N]={,,,,,,,,};
int direct[][] = {{-,},{,},{,-},{,}};
char move[] = {'u','d','l','r'};
char rmove[] = {'d','u','r','l'};
char visit[MAXNUM];
bool flag;
string paths[MAXNUM], fpath;
queue<node_st> que, rque; inline int cantor(node_st node) {
int i, j, cnt, val = ; for (i=; i<N; ++i) {
cnt = ;
for (j=i+; j<N; ++j)
if (node.map[j] < node.map[i])
++cnt;
val += fact[N--i]*cnt;
} return val;
} inline bool invNum(node_st node) {
int i, j, cnt = ; for (i=; i<N; ++i) {
if (node.map[i] == 'x')
continue;
for (j=i-; j>=; --j)
if (node.map[j]!='x' && node.map[j]>node.map[i])
++cnt;
} return cnt&;
} void bfs() {
int x, y, can;
node_st node = que.front();
que.pop(); for (int i=; i<; ++i) {
x = node.xpos/ + direct[i][];
y = node.xpos% + direct[i][];
if (x< || x>= || y< || y>=)
continue;
node_st p(node);
p.map[p.xpos] = node.map[x*+y];
p.xpos = x*+y;
p.map[p.xpos] = 'x';
can = cantor(p);
if (visit[can] == )
continue;
p.path += move[i];
if (visit[can] == -) {
flag = false;
reverse(paths[can].begin(), paths[can].end());
fpath = p.path + paths[can];
return ;
}
visit[can] = ;
paths[can] = p.path;
que.push(p);
}
} void rbfs() {
int x, y, can;
node_st node = rque.front();
rque.pop(); for (int i=; i<; ++i) {
x = node.xpos/ + direct[i][];
y = node.xpos% + direct[i][];
if (x< || x>= || y< || y>=)
continue;
node_st p(node);
p.map[p.xpos] = node.map[x*+y];
p.xpos = x*+y;
p.map[p.xpos] = 'x';
can = cantor(p);
if (visit[can] == -)
continue;
p.path += rmove[i];
if (visit[can] == ) {
flag = false;
reverse(p.path.begin(), p.path.end());
fpath = paths[can] + p.path;
}
visit[can] = -;
paths[can] = p.path;
rque.push(p);
}
} int main() {
node_st node, enode;
int i, n, can; for (i=; i<N; ++i)
enode.map[i-] = i + '';
enode.map[N-] = 'x';
enode.xpos = N-; while (scanf("%c%*c", &node.map[]) != EOF) {
for (i=; i<N; ++i) {
if (i)
scanf("%c%*c", &node.map[i]);
if (node.map[i] == 'x')
node.xpos = i;
}
if ( invNum(node) ) {
printf("unsolvable\n");
continue;
}
can = cantor(node);
if ( can == ) {
printf("\n");
continue;
}
while ( !que.empty() )
que.pop();
while ( !rque.empty() )
rque.pop();
memset(visit, , sizeof(visit));
flag = true;
rque.push(enode);
visit[] = -;
que.push(node);
visit[can] = ;
while (flag) {
n = que.size();
while (flag && n--)
bfs();
n = rque.size();
while (flag && n--)
rbfs();
}
cout <<fpath<<endl;
} return ;
}

3. A-star h函数为曼哈顿距离,必须用内联才不会TLE。

 #include <iostream>
#include <queue>
#include <stack>
#include <string>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std; #define N 9
#define MAXN 362880
//#define myabs(x) ((x)>0) ? (x):(-(x)) typedef struct node_st {
char map[N];
int xpos;
int s, p;
friend bool operator < (node_st a, node_st b) {
return a.p > b.p;
}
} node_st; char visit[MAXN];
int fact[N] = {,,,,,,,,};
int direct[][] = {{-,},{,},{,-},{,}};
char move[] = {'u', 'd', 'l', 'r'};
int pre[MAXN], bcan;
char op[MAXN];
node_st beg; inline int cantor(node_st node) {
int i, j, cnt, val = ; for (i=; i<N; ++i) {
cnt = ;
for (j=i+; j<N; ++j)
if (node.map[j] < node.map[i])
++cnt;
val += fact[N--i]*cnt;
} return val;
} inline myabs(int x) {
return (x>) ? x:-x;
} inline int h(node_st node) {
int tmp, val = ; for (int i=; i<N; ++i) {
if (node.map[i] == 'x') continue;
tmp = node.map[i] - '';
val += myabs(tmp/-i/) + myabs(tmp%-i%);
} return val;
} inline bool invNum(node_st node) {
int i, j, cnt = ; for (i=; i<N; ++i) {
if (node.map[i] == 'x') continue;
for (j=i-; j>=; --j)
if (node.map[j]!='x' && node.map[j]>node.map[i])
++cnt;
} return cnt&;
} void bfs() {
priority_queue<node_st> que;
node_st node;
int i, t1, t2, x, y, can, pcan; que.push(beg);
memset(visit, , sizeof(visit));
visit[bcan] = ; while ( !que.empty() ) {
node = que.top();
que.pop();
t1 = node.xpos / ;
t2 = node.xpos % ;
pcan = cantor(node);
for (i=; i<; ++i) {
x = t1 + direct[i][];
y = t2 + direct[i][];
if (x< || x>= || y< || y>=)
continue;
node_st p(node);
p.map[node.xpos] = p.map[x*+y];
p.xpos = x*+y;
p.map[p.xpos] = 'x';
can = cantor(p);
if (visit[can])
continue;
visit[can] = ;
++p.s;
p.p = p.s + h(p);
pre[can] = pcan;
op[can] = move[i];
if (can == )
return ;
que.push(p);
}
}
} int main() {
int i, k;
stack<char> st; while (scanf("%c%*c", &beg.map[]) != EOF) {
for (i=; i<N; ++i) {
if (i)
scanf("%c%*c", &beg.map[i]);
if (beg.map[i] == 'x')
beg.xpos = i;
}
beg.s = ;
beg.p = h(beg);
if ( invNum(beg) ) {
printf("unsolvable\n");
continue;
}
bcan = cantor(beg);
if (bcan == ) {
printf("\n");
continue;
}
bfs();
k = ;
while (k != bcan) {
st.push(op[k]);
k = pre[k];
} while ( !st.empty() ) {
printf("%c", st.top());
st.pop();
}
printf("\n");
}
return ;
}

4. IDA*,该算法其实是迭代dfs。H函数还是曼哈顿距离。

 #include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
using namespace std; #define N 9
#define MAXN 362880 typedef struct {
char map[N];
int xpos;
} node_st; int fact[N] = {,,,,,,,,};
int direct[][] = {{-,},{,},{,-},{,}};
char move[] = {'u', 'd', 'l', 'r'};
char visit[MAXN];
char op[MAXN];
int deep;
bool flag;
node_st beg; inline int cantor(node_st node) {
int i, j, cnt, val = ; for (i=; i<N; ++i) {
cnt = ;
for (j=i+; j<N; ++j)
if (node.map[j] < node.map[i])
++cnt;
val += fact[N--i]*cnt;
} return val;
} inline bool invNum(node_st node) {
int i, j, cnt = ; for (i=; i<N; ++i) {
if (node.map[i] == 'x') continue;
for (j=i-; j>=; --j)
if (node.map[j]!='x' && node.map[j]>node.map[i])
++cnt;
} return cnt&;
} inline int myabs(int x) {
return (x<) ? -x:x;
} inline int h(node_st node) {
int i, tmp, val = ; for (i=; i<N; ++i) {
if (node.map[i] == 'x') continue;
tmp = node.map[i] - '';
val += myabs(tmp/-i/) + myabs(tmp%-i%);
} return val;
} void dfs(int d) {
int i, t1, t2, x, y, can; t1 = h(beg);
if (t1 == ) {
flag = false;
return ;
}
if (t1+d > deep)
return ;
t1 = beg.xpos / ;
t2 = beg.xpos % ;
for (i=; i<; ++i) {
x = t1 + direct[i][];
y = t2 + direct[i][];
if (x< || x>= || y< || y>=)
continue;
node_st p(beg), org(beg);
p.map[p.xpos] = p.map[x*+y];
p.xpos = x*+y;
p.map[p.xpos] = 'x';
can = cantor(p);
if (visit[can]) continue;
visit[can] = ;
op[d] = move[i];
beg = p;
dfs(d+);
if ( !flag )
return ;
beg = org;
visit[can] = ;
}
} int main() {
int i; while (scanf("%c%*c", &beg.map[]) != EOF) {
for (i=; i<N; ++i) {
if (i)
scanf("%c%*c", &beg.map[i]);
if (beg.map[i] == 'x')
beg.xpos = i;
}
if ( invNum(beg) ) {
printf("unsolvable\n");
continue;
}
memset(visit, , sizeof(visit));
memset(op, , sizeof(op));
i = cantor(beg);
visit[i] = ;
deep = h(beg);
flag = true;
while (flag) {
++deep;
dfs();
//printf("%d\n", deep);
} i = ;
while ( op[i] )
printf("%c", op[i++]);
printf("\n");
} return ;
}

【HDOJ】1043 Eight的更多相关文章

  1. 【HDOJ】4729 An Easy Problem for Elfness

    其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...

  2. 【BZOJ】1043: [HAOI2008]下落的圆盘(计算几何基础+贪心)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1043 唯一让我不会的就是怎么求圆的周长并QAAQ... 然后发现好神!我们可以将圆弧变成$[0, 2 ...

  3. 【HDOJ】【3506】Monkey Party

    DP/四边形不等式 裸题环形石子合并…… 拆环为链即可 //HDOJ 3506 #include<cmath> #include<vector> #include<cst ...

  4. 【HDOJ】【3516】Tree Construction

    DP/四边形不等式 这题跟石子合并有点像…… dp[i][j]为将第 i 个点开始的 j 个点合并的最小代价. 易知有 dp[i][j]=min{dp[i][j] , dp[i][k-i+1]+dp[ ...

  5. 【HDOJ】【3480】Division

    DP/四边形不等式 要求将一个可重集S分成M个子集,求子集的极差的平方和最小是多少…… 首先我们先将这N个数排序,容易想到每个自己都对应着这个有序数组中的一段……而不会是互相穿插着= =因为交换一下明 ...

  6. 【HDOJ】【2829】Lawrence

    DP/四边形不等式 做过POJ 1739 邮局那道题后就很容易写出动规方程: dp[i][j]=min{dp[i-1][k]+w[k+1][j]}(表示前 j 个点分成 i 块的最小代价) $w(l, ...

  7. 【HDOJ】【3415】Max Sum of Max-K-sub-sequence

    DP/单调队列优化 呃……环形链求最大k子段和. 首先拆环为链求前缀和…… 然后单调队列吧<_<,裸题没啥好说的…… WA:为毛手写队列就会挂,必须用STL的deque?(写挂自己弱……s ...

  8. 【HDOJ】【3530】Subsequence

    DP/单调队列优化 题解:http://www.cnblogs.com/yymore/archive/2011/06/22/2087553.html 引用: 首先我们要明确几件事情 1.假设我们现在知 ...

  9. 【HDOJ】【3068】最长回文

    Manacher算法 Manacher模板题…… //HDOJ 3068 #include<cstdio> #include<cstring> #include<cstd ...

随机推荐

  1. Tomcat 的 SSL 配置

    本教程使用 JDK 6 和 Tomcat 7,其他版本类似. 基本步骤: 使用 java 创建一个 keystore 文件 配置 Tomcat 以使用该 keystore 文件 测试 配置应用以便使用 ...

  2. JS时间戳

    var timestamp1 = Date.parse(new Date()); var timestamp2 = Date.parse(new Date()); var times = timest ...

  3. extSourceStat_7Day_Orders.php

    <?php /** Log文件格式2012/7/4 列号 字段含义 取值 ------------------------------------------------------------ ...

  4. jQuery获取radio选中项的值【转藏】

    <title></title> <script src="js/jquery-1.7.2.min.js"></script> < ...

  5. FOR XML PATH实现小九九

    数据库环境:SQL SERVER2008R2 今天我们用SQL实现一下九九乘法表的功能. 实现的逻辑不是很复杂,难点在于怎么把想要的内容从同一列里头拼接到同一行上. 在这里,我们用到了FOR XML ...

  6. oracle的购买价格研究

    如果你是一个架构师,在数据库选型上除了技术选型,更重要的可能是性价比的选择,而oracle是现今排名第一的数据库,因此对oracle的价格有所了解是必须的. 几个要点: 1.oracle授权(也就是购 ...

  7. java中事件处理探究

    事件的触发可以源于用户,也可以用代码来主动设置事件的发生.如setSelected()java.awt.event中 听众接口 事件类 适配器类 ComponentListener     Conta ...

  8. Codevs 1065 01字符串

    1065 01字符串 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 传送门 题目描述 Description 输出仅有0和1组成的长度为n的字符串,并且其中不能含有 ...

  9. vecor预分配内存溢出2

    vector预分配内存溢出导致原始的 迭代器 失效 consider what happens when you add the one additional object that causes t ...

  10. PC110304/UVA850

    这题目WA了好几次,主要是我没有理解清楚No solution.这个情况. 如果在match原文做好了,基本map一下就能过了. 与原句match的条件就是: 1.出现了26个字母 2.该空格的地方要 ...