藍橋杯 歷屆試題 九宮重排(廣度優先搜尋bfs)

2021-10-03 02:34:47 字數 2410 閱讀 8281

問題描述

如下面第乙個圖的九宮格中,放著 1~8 的數字卡片,還有乙個格仔空著。與空格子相鄰的格仔中的卡片可以移動到空格中。經過若干次移動,可以形成第二個圖所示的局面。

我們把第乙個圖的局面記為:12345678.

把第二個圖的局面記為:123.46758

顯然是按從上到下,從左到右的順序記錄數字,空格記為句點。

本題目的任務是已知九宮的初態和終態,求最少經過多少步的移動可以到達。

如果無論多少步都無法到達,則輸出-1。

輸入格式

輸入第一行包含九宮的初態,第二行包含九宮的終態。

輸出格式

輸出最少的步數,如果不存在方案,則輸出-1。

樣例輸入

12345678.

123.46758

樣例輸出

3樣例輸入

13524678.

46758123.

樣例輸出

22——分割線——

分析:本題和「歷屆試題 青蛙跳杯子」同屬一種型別

都是給出乙個初態和乙個目標態,讓我們輸出從初態轉變為目標態所需的最小步數

不同的是,在「歷屆試題 青蛙跳杯子」這道題中,我們處理的字串在發生位置交換時是乙個一維的變換(只有向左或向右,則對應用加或減來刻畫即可),並且對於所有位置上都通用,於是可以設定乙個dir陣列,在裡面存放所有的位置變換操作即可;而在本題中,由於給出的是乙個九宮格,因此在處理字串發生位置交換時是乙個二維的變換(此時有上、下、左、右四個方向的變換)。於是在這裡就引出了乙個新問題:每個點位置變換時並不一致,我們如何處理。如下所示:

我們可以發現:

與格點0直接相鄰的點有格點1和格點3(與之類似的還有格點2、格點6、格點8)

與格點1直接相鄰的點有格點0、格點2和格點4(與之類似的還有格點3、格點5、格點7)

與格點4直接相鄰的點有格點1、格點3、格點5和格點7

這時我們換一種思路,把這個九宮格視為乙個長度為9的字串(降維至一維):012345678

此時再把這字串上每個位置能直接移動過去的點都放進乙個陣列dir[ ][ ]中,如:

在點0處能移動至點1和點3,則dir[0][0]=1,dir[0][1]=3

在點1處能移動至點0、點2和點4,則dir[1][0]=0,dir[1][1]=2,dir[1][2]=4

在點4處能移動至點1、點3、點5和點7,則dir[4][0]=1,dir[4][1]=3,dir[4][2]=5,dir[4][3]=7

……由於從上圖的結論中我們知道,在九宮格中主要有三類點,一類的直接相鄰點為2,一類為3,還有乙個為4。因此為了在程式中能更方便使用dir[ ][ ],我們還需要為每個出發點設定好其可移動方案的數量,這裡可以再次定義乙個dircount[ ]陣列來存放,如:

在點0處能移動至其他兩個點,則dircount[0]=2

在點1處能移動至其他三個點,則dircount[1]=3

在點4處能移動至其他四個點,則dircount[4]=4

……當解決了上述問題後,這道題就和歷屆試題 青蛙跳杯子一樣了

接下來只需要利用bfs來對整個初始字串進行搜尋即可

——分割線——

下面直接給出本題的完整**:

#include

#include

#include

#include

using

namespace std;

//初始化每個點能直接移動過去的點

int dir[9]

[4]=

,,,,

,,,,

};int dircount=

;//每個點可移動方案的數量

struct situation

intgetpos()

//返回當前字串中 空格的位置 };

queue q;

set s;

void

bfs(string start,string target)

q.push

(situation

(start,0)

);s.insert

(start)

;while

(!q.

empty()

)if(!s.

count

(str)

)swap

(str[pos]

,str[dir[pos]

[i]]);

//恢復現場 }}

cout<

<

}int

main()

藍橋杯 歷屆試題 九宮重排

問題描述 如下面第乙個圖的九宮格中,放著 1 8 的數字卡片,還有乙個格仔空著。與空格子相鄰的格仔中的卡片可以移動到空格中。經過若干次移動,可以形成第二個圖所示的局面。我們把第乙個圖的局面記為 12345678.把第二個圖的局面記為 123.46758 顯然是按從上到下,從左到右的順序記錄數字,空格...

藍橋杯 歷屆試題 九宮重排

問題描述 如下面第乙個圖的九宮格中,放著 1 8 的數字卡片,還有乙個格仔空著。與空格子相鄰的格仔中的卡片可以移動到空格中。經過若干次移動,可以形成第二個圖所示的局面。我們把第乙個圖的局面記為 12345678.把第二個圖的局面記為 123.46758 顯然是按從上到下,從左到右的順序記錄數字,空格...

藍橋杯 歷屆試題 九宮重排

bfs 查重 因為通過不同的路徑到達同乙個點會產生不同的串,不具有唯一性,所以查重不再是查詢乙個點到沒到過,而是找乙個中間串出沒出現過,set一下就行了 include include include include include include include include include i...