这道题目最开始做的时候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. mac os 终端提示 you have new mail

    这里的信息可能是由于所做的什么操作触发了发邮件的事件, 系统发送的邮件提醒. 我遇到的原因是由于运行 cron , 由于权限所导致了发邮件的事件提醒. Last login: Tue Apr 26 0 ...

  2. CentOS6.5编译安装最新MySQL 5.7.11

    安装前工作:1,从官方网址下载MySQL5.7.11源码包,大概49M2,安装好CentOS6.5 64位操作系统.建议update操作系统,以便是此版本最新的3. yum -y install  g ...

  3. css动画结束后 js无法修改translated值 .

    由于项目的需要,俺要做一些页面的转场动画. 即将是移动端,肯定是首先css动画了. 结果确发现,css动画中,如果设置animation-fill-mode: both;在动画结束后无法个性trans ...

  4. 如何用js检测判断时间日期的间距

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  5. Spring4.3.1 JDBCTemplate操作数据库

    个人总结,转载请注明出处:http://www.cnblogs.com/lidabnu/p/5679354.html 基于Spring4.3.1官方文档总结,官方文档链接http://docs.spr ...

  6. javascript-设置div隐藏

    html code: <div class="title"> <ul id="col02_left_title"> <li> ...

  7. (五)Struts2 标签

    所有的学习我们必须先搭建好Struts2的环境(1.导入对应的jar包,2.web.xml,3.struts.xml) 第一节:Struts2 标签简介 Struts2 自己封装了一套标签,比JSTL ...

  8. iOS崩溃报告获取二

    // // JKExceptionHandler.h // JKExceptionHandler // // Created by Jack on 16/9/7. // Copyright © 201 ...

  9. asp.net web api内部培训资料

    最近在公司进行了一次asp.net web api的分享吧,不算是培训. 可能大家有些人对Web API的推出目的还不是很了解,可以看看微软官方的定义,其实是为了提供一个好的REST Service方 ...

  10. java获取远程网络图片文件流、压缩保存到本地

    1.获取远程网路的图片 /** * 根据地址获得数据的字节流 * * @param strUrl * 网络连接地址 * @return */ public static byte[] getImage ...