diff --git a/OnlineJudges/lydsy/1085.cpp b/OnlineJudges/lydsy/1085.cpp new file mode 100644 index 0000000..5c6558f --- /dev/null +++ b/OnlineJudges/lydsy/1085.cpp @@ -0,0 +1,69 @@ +#include +template +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; +} \ No newline at end of file diff --git a/省选准备/assets/day7/bzoj1085.cpp b/省选准备/assets/day7/bzoj1085.cpp new file mode 100644 index 0000000..5c6558f --- /dev/null +++ b/省选准备/assets/day7/bzoj1085.cpp @@ -0,0 +1,69 @@ +#include +template +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; +} \ No newline at end of file diff --git a/省选准备/省选基础算法.pdf b/省选准备/省选基础算法.pdf index 6dc3160..d91f2bf 100644 Binary files a/省选准备/省选基础算法.pdf and b/省选准备/省选基础算法.pdf differ diff --git a/省选准备/省选基础算法.tex b/省选准备/省选基础算法.tex index 60e5870..80dc29e 100644 --- a/省选准备/省选基础算法.tex +++ b/省选准备/省选基础算法.tex @@ -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} \ No newline at end of file