【HDOJ】1043 Eight
这道题目最开始做的时候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的更多相关文章
- 【HDOJ】4729 An Easy Problem for Elfness
其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...
- 【BZOJ】1043: [HAOI2008]下落的圆盘(计算几何基础+贪心)
http://www.lydsy.com/JudgeOnline/problem.php?id=1043 唯一让我不会的就是怎么求圆的周长并QAAQ... 然后发现好神!我们可以将圆弧变成$[0, 2 ...
- 【HDOJ】【3506】Monkey Party
DP/四边形不等式 裸题环形石子合并…… 拆环为链即可 //HDOJ 3506 #include<cmath> #include<vector> #include<cst ...
- 【HDOJ】【3516】Tree Construction
DP/四边形不等式 这题跟石子合并有点像…… dp[i][j]为将第 i 个点开始的 j 个点合并的最小代价. 易知有 dp[i][j]=min{dp[i][j] , dp[i][k-i+1]+dp[ ...
- 【HDOJ】【3480】Division
DP/四边形不等式 要求将一个可重集S分成M个子集,求子集的极差的平方和最小是多少…… 首先我们先将这N个数排序,容易想到每个自己都对应着这个有序数组中的一段……而不会是互相穿插着= =因为交换一下明 ...
- 【HDOJ】【2829】Lawrence
DP/四边形不等式 做过POJ 1739 邮局那道题后就很容易写出动规方程: dp[i][j]=min{dp[i-1][k]+w[k+1][j]}(表示前 j 个点分成 i 块的最小代价) $w(l, ...
- 【HDOJ】【3415】Max Sum of Max-K-sub-sequence
DP/单调队列优化 呃……环形链求最大k子段和. 首先拆环为链求前缀和…… 然后单调队列吧<_<,裸题没啥好说的…… WA:为毛手写队列就会挂,必须用STL的deque?(写挂自己弱……s ...
- 【HDOJ】【3530】Subsequence
DP/单调队列优化 题解:http://www.cnblogs.com/yymore/archive/2011/06/22/2087553.html 引用: 首先我们要明确几件事情 1.假设我们现在知 ...
- 【HDOJ】【3068】最长回文
Manacher算法 Manacher模板题…… //HDOJ 3068 #include<cstdio> #include<cstring> #include<cstd ...
随机推荐
- spring jar包、文档官网下载
一.spring的官方网址:http://spring.io/ 二.看到这个简洁清新的界面,导航很明确,进入projects whatever the infrastructure needs of ...
- input框中的背景文字
<input placeholder="入库单单号" type="text" ><button>查找</button>
- 逻辑回归应用之Kaggle泰坦尼克之灾(转)
正文:14pt 代码:15px 1 初探数据 先看看我们的数据,长什么样吧.在Data下我们train.csv和test.csv两个文件,分别存着官方给的训练和测试数据. import pandas ...
- .NET设计模式(8):适配器模式(Adapter Pattern)
):适配器模式(Adapter Pattern) 适配器模式(Adapter Pattern) --.NET设计模式系列之八 Terrylee,2006年2月 概述 在软件系统中,由于应用环境的 ...
- Socket服务器整体架构概述
转载:http://www.cnblogs.com/tianzhiliang/archive/2010/10/28/1863684.html Socket服务器主要用于提供高效.稳定的数据处理.消息转 ...
- 一道JS addEventListener面试题
在园里看到一道面试题,<div id="test">Click Here</div> var node=document.getElementById('t ...
- Qt中,当QDockWidget的父窗口是一个不可以拖动的QTabWidget的时候实现拖动的方法
之前在做有关QDockWidget的内容时候遇到了瓶颈,那就是窗口弹出来之后拖动不了,也不可以放大和缩小,若是弹出来之后设置成了window的flags,也不可以拖动,而且也不是需要的效果. 1.弹出 ...
- 中文翻译:pjsip教程(一)之PJNATH简介
在学习pjsip的过程中,发现只是单单的阅读英文官方文档,对于里边概念的理解还是不够透彻,并且苦于pjsip没有发现全一点的中文版本,所以想尽自己所能为建设和谐社会而贡献一份力量,文中定会有所疏漏,希 ...
- 安装sql server 2008,提示要删除SQL Server 2005 Express 工具 怎么解决?
x86 修改注册表:HKLM\Software\Microsoft\Microsoft SQL Server\90\Tools\ShellSEM,把 ShellSEM重命名即可. x64 ...
- php递归数组中的应用
<?php $arr = array(array(1,2), array(3, 4), array(array(5, 6), array(7, 8)));function t($a){ i ...