Section 7.4

master
大蒟蒻 9 years ago
parent 46f151a0d9
commit 5f916ae0c8

@ -0,0 +1,69 @@
#include <cstdio>
template <typename T>
inline void swap(T &a, T &b)
{
T t = a;
a = b;
b = t;
}
const char des[5][5] = { {'1', '1', '1', '1', '1'},
{'0', '1', '1', '1', '1'},
{'0', '0', '*', '1', '1'},
{'0', '0', '0', '0', '1'},
{'0', '0', '0', '0', '0'} };
const int dx[] = { 1, 2, 2, 1, -1, -2, -2, -1 };
const int dy[] = { -2, -1, 1, 2, 2, 1, -1, -2 };
const int Move[8][2] = { {1, -2}, {2, -1}, {2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2} };
char cur[5][5];
#define H() \
((cur[0][0] != des[0][0]) + (cur[0][1] != des[0][1]) + \
(cur[0][2] != des[0][2]) + (cur[0][3] != des[0][3]) + \
(cur[0][4] != des[0][4]) + (cur[1][0] != des[1][0]) + \
(cur[1][1] != des[1][1]) + (cur[1][2] != des[1][2]) + \
(cur[1][3] != des[1][3]) + (cur[1][4] != des[1][4]) + \
(cur[2][0] != des[2][0]) + (cur[2][1] != des[2][1]) + \
(cur[2][2] != des[2][2]) + (cur[2][3] != des[2][3]) + \
(cur[2][4] != des[2][4]) + (cur[3][0] != des[3][0]) + \
(cur[3][1] != des[3][1]) + (cur[3][2] != des[3][2]) + \
(cur[3][3] != des[3][3]) + (cur[3][4] != des[3][4]) + \
(cur[4][0] != des[4][0]) + (cur[4][1] != des[4][1]) + \
(cur[4][2] != des[4][2]) + (cur[4][3] != des[4][3]) + \
(cur[4][4] != des[4][4]) - 1)
inline bool can(int x, int y)
{
return 0 <= x && x <= 4 && 0 <= y && y <= 4;
}
int DEP;
bool dfs(int x, int y, int step)
{
if (step == DEP) return H() == -1;
if (H() + step > DEP) return false;
for (int i = 0, nx, ny; i < 8; i++)
if (can(nx = x + dx[i], ny = y + dy[i]))
{
swap(cur[x][y], cur[nx][ny]);
if (dfs(nx, ny, step + 1)) return true;
swap(cur[x][y], cur[nx][ny]);
}
return false;
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
for (int i = 0; i < 5; i++)
scanf("%s", cur[i]);
int si = -1, sj = -1;
for (int i = 0; i < 5; i++)
for (int j = 0; j < 5; j++)
if (cur[i][j] == '*')
si = i, sj = j;
for (DEP = 0; DEP <= 15; DEP++)
if (dfs(si, sj, 0))
break;
printf("%d\n", DEP > 15 ? -1 : DEP);
}
return 0;
}

@ -0,0 +1,69 @@
#include <cstdio>
template <typename T>
inline void swap(T &a, T &b)
{
T t = a;
a = b;
b = t;
}
const char des[5][5] = { {'1', '1', '1', '1', '1'},
{'0', '1', '1', '1', '1'},
{'0', '0', '*', '1', '1'},
{'0', '0', '0', '0', '1'},
{'0', '0', '0', '0', '0'} };
const int dx[] = { 1, 2, 2, 1, -1, -2, -2, -1 };
const int dy[] = { -2, -1, 1, 2, 2, 1, -1, -2 };
const int Move[8][2] = { {1, -2}, {2, -1}, {2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2} };
char cur[5][5];
#define H() \
((cur[0][0] != des[0][0]) + (cur[0][1] != des[0][1]) + \
(cur[0][2] != des[0][2]) + (cur[0][3] != des[0][3]) + \
(cur[0][4] != des[0][4]) + (cur[1][0] != des[1][0]) + \
(cur[1][1] != des[1][1]) + (cur[1][2] != des[1][2]) + \
(cur[1][3] != des[1][3]) + (cur[1][4] != des[1][4]) + \
(cur[2][0] != des[2][0]) + (cur[2][1] != des[2][1]) + \
(cur[2][2] != des[2][2]) + (cur[2][3] != des[2][3]) + \
(cur[2][4] != des[2][4]) + (cur[3][0] != des[3][0]) + \
(cur[3][1] != des[3][1]) + (cur[3][2] != des[3][2]) + \
(cur[3][3] != des[3][3]) + (cur[3][4] != des[3][4]) + \
(cur[4][0] != des[4][0]) + (cur[4][1] != des[4][1]) + \
(cur[4][2] != des[4][2]) + (cur[4][3] != des[4][3]) + \
(cur[4][4] != des[4][4]) - 1)
inline bool can(int x, int y)
{
return 0 <= x && x <= 4 && 0 <= y && y <= 4;
}
int DEP;
bool dfs(int x, int y, int step)
{
if (step == DEP) return H() == -1;
if (H() + step > DEP) return false;
for (int i = 0, nx, ny; i < 8; i++)
if (can(nx = x + dx[i], ny = y + dy[i]))
{
swap(cur[x][y], cur[nx][ny]);
if (dfs(nx, ny, step + 1)) return true;
swap(cur[x][y], cur[nx][ny]);
}
return false;
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
for (int i = 0; i < 5; i++)
scanf("%s", cur[i]);
int si = -1, sj = -1;
for (int i = 0; i < 5; i++)
for (int j = 0; j < 5; j++)
if (cur[i][j] == '*')
si = i, sj = j;
for (DEP = 0; DEP <= 15; DEP++)
if (dfs(si, sj, 0))
break;
printf("%d\n", DEP > 15 ? -1 : DEP);
}
return 0;
}

@ -532,4 +532,7 @@ Manacher 模板题
假设$M$是二分图$G$的一个匹配,则称$M$中边所依附的顶点是已匹配的顶点,若$P$是图$G$中一条连通两个未匹配顶点的路径,并且不属于$M$的边和属于$M$的边(即待匹配的边和已匹配边)在$P$上交替出现,则称$P$为相对于$M$的一条增广路径。如果我们将$P$的路径看着边的集合,我们令$M'=M \mathop{xor} P$,则$M'$是比$M$多一条边的匹配,即更大的匹配$M'$包含了,或者属于$M$,或者属于$P$,但不同时属于$M$$P$的边。当找不到增广路的时候,则这时候的$M$是最大匹配。
\paragraph{例题} 把光束当作图的顶点,小行星当作连接对应光束的边。
\codeinput[\href{http://poj.org/problem?id=3041}{POJ3041} - Asteroids]{assets/day7/poj3041.cpp}
\subsection{迭代加深搜索} 通过搜索的办法来判断是否有不超过某个$x$的解。把$x$$0$开始每次增加$1$,那么首次找到解时的$x$便是最优解。这种搜索就被称为迭代加深搜索(IDDFS)。如果加上状态$v$到目标状态的距离下界的估价函数$h^*(v)$进行提前剪枝优化后的算法则称为IDA*。但要保证$h^*(v)$的值小于真实的值,否则会导致错误的剪枝。
\paragraph{例题} 估价函数:还没有走到正确位置上的棋子的个数
\codeinput[\href{http://www.lydsy.com/JudgeOnline/problem.php?id=1085}{BZOJ1085} - 骑士精神]{assets/day7/bzoj1085.cpp}
\end{document}
Loading…
Cancel
Save