这道题目最开始做的时候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. json <--->List集合,实体类 之间的相互转换

    json所依赖的jar包http://files.cnblogs.com/files/wenjie123/json_jar%E5%8C%85.rar package com.hp.svse; impo ...

  2. python 验证码

    python写的验证码小程序 ##################验证码,数字+字母 import random check_code="" for i in range(6): ...

  3. CentOS7上Nginx的使用

    Nginx 的启动 指定配置文件的方式启动nginx # nginx -c /etc/nginx/nginx.conf 对于yum安装的nginx,使用systemctl命令启动 # systemct ...

  4. SQL语句中格式化时间

    给数据库中的字段格式化(): to_char(CREATETIME,'yyyy-MM-dd') 给程序中的字段格式化(InTime为数据库字段): InTime = to_date( '" ...

  5. 3DES加解密【示例】

    代码 /**  * 3DES加解密  */ public class DESedeUtils {     private static final String ALGORITHM_MD5 = &qu ...

  6. php递归创建目录

    /** * 递归创建目录 * @param [string] $path [创建的目录] * @return [type] [description] */ function mk_Dir($path ...

  7. C#结构内存布局介绍

    转载:http://www.csharpwin.com/csharpspace/10455r2800.shtml 本来打算写一篇文章,详细地讨论一下结构的内存布局,但是想了下,跟路西菲尔的这篇文章也差 ...

  8. o] TortoiseGit错误 - Could not get all refs. libgit2 returned: corrupted loose reference file

    因无法追溯的同步操作错误或工程文件错误,造成Git 同步时报错: Could not get all refs. libgit2 returned: corrupted loose reference ...

  9. 对于EditText的详细用法

    EditText这个控件对于每一个Android开发者来说都是再熟悉不过了,但是,为什么有的人的EditText可以表现的那么好看,而刚入学Android的程序员来讲却丑到爆.这就充分的说明对于Edi ...

  10. C语言开发环境配置

    链接:http://pan.baidu.com/s/1qWkpD72 密码:zhig 将解压包直接解压放在C盘下. 右击我的电脑,点属性—>高级—>环境变量然后在PATH里加入C:\Min ...