Project Euler 244
Project Euler 244
题目
Sliders
You probably know the game Fifteen Puzzle. Here, instead of numbered tiles, we have seven red tiles and eight blue tiles.
A move is denoted by the uppercase initial of the direction (Left, Right, Up, Down) in which the tile is slid, e.g. starting from configuration (S), by the sequence LULUR we reach the configuration (E):
(S),(E)
For each path, its checksum is calculated by (pseudocode):
\(\begin{aligned} \text{checksum} &= 0\\ \text{checksum} &= (\text{checksum} \times 243 + m_1) \bmod 100000007\\ \text{checksum} &= (\text{checksum} \times 243 + m_2) \bmod 100000007\\ &\dots&\\ \text{checksum} &= (\text{checksum} \times 243 + m_n) \bmod 100000007 \end{aligned}\)
where \(m_k\) is the ASCII value of the \(k^{\text{th}}\) letter in the move sequence and the ASCII values for the moves are:
L | \(76\) |
R | \(82\) |
U | \(85\) |
D | \(68\) |
For the sequence LULUR given above, the checksum would be \(19761398\). Now, starting from configuration (S), find all shortest ways to reach configuration (T).
(S),(T)
What is the sum of all checksums for the paths having the minimal length?
解决方案
考虑使用广度优先搜素进行,从节点S到节点T处理出所有路径。
不过,在实际的实现过程中发现,如果从S到某个节点U的最短路径\(\text{checksum}\)之和,全部乘\(243\)再添加一个方向的ASCII码后就可以成为下一个未遍历节点的\(\text{checksum}\)之和的一部分。因此实际上不需要求出所有最短路径并枚举,只需要维护S到当前的节点的\(\text{checksum}\)之和即可。
为了节省存储空间,将棋盘编码成了一个\(16\)位三进制数,以作为两个字典的键。
代码
1 | from queue import Queue |