時間限制:10000ms
單點時限:1000ms
記憶體限制:256mb
描述小hi:小ho你會下西洋棋麼?
小ho:應該算會吧,我知道每個棋子的移動方式,馬走日象飛田什麼的...
小hi:象飛田那是中國象棋啦!
小ho:哦,對。西洋棋好像是走斜線來著。
小hi:不過馬走日倒是對了。西洋棋中的馬一般叫做騎士,關於它有個很有意思的問題。
小ho:什麼啊?
小hi:騎士巡遊問題,簡單來說就是關於在棋盤上放置若干個騎士,然後**移動這些騎士是否能滿足一定的而要求。舉個例子啊:乙個騎士從起始點開始,能否經過棋盤上所有的格仔再回到起點。
小ho:哦,看上去好像很難的樣子。
小hi:其實也還好了。簡單一點的比如棋盤上有3個騎士,能否通過若干次移動走到一起。
小ho:能夠麼?
小hi:當然能夠了。由於騎士特殊的移動方式,放置在任何乙個初始位置的騎士,都可以通過若干次移動到達棋盤上任意乙個位置。
小ho:那麼只要選定乙個位置,把它們全部移動過去就好了是吧?
小hi:是的,那麼這裡又有另乙個問題了:要選擇哪乙個位置匯合,使得3個騎士行動的總次數最少?
小ho:嗯,這個好像不是很難,讓我想一想。
輸入第1行:1個正整數t,表示資料組數,2≤t≤10。
第2..t+1行:用空格隔開的3個座標, 每個座標由2個字元ab組成,a為'a'~'h'的大寫字母,b為'1'~'8'的數字,表示3個棋子的初始位置。
輸出第1..t行:每行1個數字,第i行表示第i組資料中3個棋子移動到同一格的最小行動步數。
樣例輸入
2樣例輸出a1 a1 a1
b2 d3 f4
02
思路:利用佇列做bfs,求出當前位置到棋盤上所有位置的最短距離,然後,三個棋子到棋盤位置的最短距離和
ac**:
1 #include "iostream
"2 #include "
string.h
"3 #include "
queue"4
5using
namespace
std;
67 typedef pairpii;
8char ss[3];9
int vis[3][8][8
];10
int d[8][2] = ,,,,,,, };
11int step = 0;12
13 pii pos; //
馬位置14
15bool
in(pii p)
1622
23void bfs(int vi[8][8
])2445}
46}47}
4849
intmain()
5077
if (temp 78 ans =temp;
79} 80}
81 cout << ans <83 }
補充:提供另一種思路,因為是8x8的棋盤,可以模擬成8進製的乙個數,這樣3個旗子就是乙個6位的8進製數。
由此可以通過乙個大小為8^6的布林陣列來進行狀態的判重。而每一次的狀態轉移也從原來的僅列舉8個方向,變成了列舉騎士加列舉方向,一共有3*8=24種可能。
此方法的偽**為:
queue.push( initialstatus ) // 將初始的8進製數加入佇列中在進行檢查是否已經走到一起時,可以通過乙個位運算來做:while (!queue.isempty())
now_status = queue.pop() // 彈出佇列頭元素
for i = 1 .. 3
// 列舉移動的其實
for j = 1 .. 8
// 列舉8種可能的移動
next_status = move(now_status, i, j) // 移動騎士並記錄狀態
if (next_status is valid and not visited[ next_status ])
step[ next_status ] = step[ now_status ] + 1
queue.push( next_status )
if (check(next_status)) then
// 檢查這個八進位制數是否滿足3個座標重合
return step[ next_status ]
end if
end if
end for
end while
check(status):小ho:哦,這樣就可以不用計算出每個騎士走到每個點的步數,而是在過程中就有可能直接求解到最先匯合位置的步數。return ((status and 0x3f) == ((status rsh 6) and 0x3f)) and (((status rsh 6) and 0x3f) == ((status rsh 12) and 0x3f))
// rsh表示右移操作
小hi:對,不過這個演算法中狀態的轉移會稍微複雜一點。你可以選擇乙個你比較喜歡的方法來實現。
小ho:好!
hihoCoder搜尋二 騎士問題 暴力法
直接按照提示給出的方法做,用bfs記錄每個騎士到每個點的最小距離,在求所有的最小距離的和最小的點處,得到的即為最小和。小ho 小hi你剛剛說到了這樣一點 放置在任何乙個初始位置的騎士,都可以通過若干次移動到達棋盤上任意乙個位置。那麼我就可以把整個局面分開來做 我先計算出每乙個騎士到達棋盤上每個位置的...
hiho字型大小設定(二分搜尋)
題目大概意思就是我們有n個自然段,每個自然段有ai個字元,手機螢幕寬w,長h,讓我們字元可設定的最大字型號s,比如字型號為s,則一行只能顯示 w s 向下取整個字元,乙個頁只能嫻熟 h s 行,最終所有自然段顯示的頁面不超過p頁。每乙個自然段都重新的一行開始顯示,自然段之間沒有空餘的行。基本思路就是...
hiho 1139 二分 bfs搜尋
題目 實現 include include include include include include include include include include include includeusing namespace std struct edge 邊的個數,開始的時候陣列開的長度為...