Blue Bridge Cup Selected Questions - Jumping Grasshopper

This column has been included .
In the previous lecture, we have learned BFS and programmed through a problem.
The topic of jumping grasshoppers we are talking about today also uses the BFS algorithm.
Many BFS questions are related to the weight of judgment. The principle of BFS is to gradually expand the next layer, and put the expanded next layer points into the queue for processing. At any time, the queue only contains points from two adjacent layers. If you can't understand this sentence, we might as well think about the problem of global climate , maybe you can understand it.

Topic description

As shown in the picture below: There are 9 plates arranged in a circle. Eight of the plates contained eight grasshoppers, and one was empty. We number these grasshoppers clockwise from 1 to 8.

Please add image description

image description

Each grasshopper can jump into an adjacent empty plate, or with a little more force, jump over an adjacent grasshopper into an empty plate.

Please calculate, if you want to change the formation of the grasshoppers to be counterclockwise, and keep the position of the empty disk unchanged (that is, 1-8 transposition, 2-7 transposition, ...), at least how many passes jump?

enter description

none

output description

none

Problem solving ideas and detailed answers

It's a little tricky to let the grasshopper jump directly to the empty plate, because there are so many grasshoppers jumping and dizzy. But if you look at it the other way around and let the empty plate jump to the grasshopper's position, it's much simpler, with only one empty plate jumping.
Do you feel that this is also a bit winding, let's introduce another modeling method: "turn circles into lines"! Consider the empty disk as 0, then there are 9 numbers { 0,1,2,3,4,5,6,7,8}, 9 numbers on a circle, straightened into 9 on a line​ numbers. So the question can be converted into an eight-digit problem, and the eight-digit problem is a classic BFS problem.
What is the number eight?
The eight-digit number has 9 numbers { 0,1,2,3,4,5,6,7,8}, and it has 9!=362880 permutations, which is not too much. The initial state of this question is "012345678", and the end state is "087654321". One jump from the initial state, there are 4 cases: insert image description here
so extend each layer with BFS. Each layer is the grasshopper jumping once, and when it expands to a certain layer, it finds the end point "087654321", then the depth of this layer is the number of times the grasshopper jumps.
But it is not enough to use BFS for this question.
You think, from step 1 to step 2, there are 4 kinds of jumps; from step 2 to step 3, there are 4 × 4 kinds; ......; step 2020, there are 4 20 = 1 trillion kinds! Too much! The queue of BFS will definitely not fit!
So what should I do?
**Sentence of major law! **Determine whether there are repeated jumps. If you jump to a situation that has occurred before, you don't need to jump down. There are only 9!=362880 cases in total, easy to judge. Let's analyze the code complexity: at each layer, at least 4 and at most 362880 cases can be extended. The final calculated answer is that the end point is reached at the 20th floor, so at most 20×362880=7257600 times.

Answer

def insertQueue(q: list, dir: int, news: tuple, vis: set):
    pos = news[1]   # 0的位置
    status = news[0]
    insertPos = (pos + dir + 9) % 9
    # 将字符串转为列表比较好处理
    t = list(status)
    t[pos], t[insertPos] = t[insertPos], t[pos]
    addStatus = "".join(t)
    if addStatus not in vis:
        vis.add(addStatus)
        q.append((addStatus, insertPos, news[2] + 1))

# main
q = [("012345678", 0, 0)]
vis = set()
vis.add("012345678")
while q:
    news = q.pop(0)       
    if news[0] == "087654321":    # 到达了目标状态输出最少步数
       print(news[2])
       break
    insertQueue(q, -2, news, vis)   #扩展下一层的4种情况
    insertQueue(q, -1, news, vis)
    insertQueue(q, 1, news, vis)
    insertQueue(q, 2, news, vis)

Guess you like

Origin blog.csdn.net/m0_51951121/article/details/123316286