乍一看真的無從下手,規則一臉懵逼。
首先看到第3個規則,每個棋子往任意方向都只能走3格。可以聯想一下西洋棋四個象,2個永遠在黑格,2個永遠在白格。
依照這個思路,我們只有9類位置(橫座標模3與縱座標模3都相同的位置為同一類)。
其中,每一類位置上的棋子可以通過規則3互達同一類位置,卻永遠不可能用規則3走到其他類的位置。
如下圖:(想象若干個3x3的框,左上角對齊鋪滿整個地圖,框內位置相同的即同類位置)
我們把同類位置的棋子數量求和一下,對應放到乙個3x3的九宮格裡(我們按照上圖以0~8為每類位置編號)。以下就只對這個九宮格操作就可以了,比如$x$個0類的棋子越過1個8類棋子到達4類位置,我們把0的數字減$x$,把8的數字減$x$,把4的數字加$x$。
為什麼不用考慮實際上棋子的位置呢?
根據上面標紅的性質,任意同類棋子可以互達。我不需要考慮我要操作的3枚棋子具體在什麼地方,只要將這3枚棋子移到三點一線,就可以進行規則2的操作了。
然而不是每三個位置都能移成三點一線的,受地圖大小影響,可能會出現這種情況:
比如這個案例,對於7-->8-->6的情況,我能用九宮格的數字相加減嗎?7-->5-->0呢?都不行。因為實際地圖上,並不存在乙個786、750三點一線的地方。
但是0-->6-->3、1-->7-->4、0-->7-->5都是可以用九宮格的數字進行加減操作的,因為地圖的確存在這種場所可以供棋子移動過來進行操作。
那麼我們預處理出那些類別的位置可以走2步互達(列舉原圖的位置往八個方向走2步看看走到的是什麼類別的位置)。
考慮到棋子總數只有10,我們可以用狀態壓縮記錄這個九宮格的狀態,暴力列舉即可,用map記憶一下有沒有到過這個狀態。
終止狀態即:指定終點同類位置的權值為1,且其他位置權值為0.
1 #include 2 #include 3奇妙**#define min(a,b) (a4
using
namespace
std;
5 typedef long
long
ll;6
const
intbase=11,xx[8]=,yy[8]=;
7int
k,n,m,x0,y0;
8int can[9][9
];9 ll bin[10
],bigsta,finsta;
10 mapint>ans;
11 inline int trans(int x)
12void
getdirection()25}
26}27bool
dfs(ll s)
36int
u,v,p,x,y,px,py;
37for(int i=0;i<3;i++)
38for(int j=0;j<3;j++)50}
51 ans[s]=2;52
return
false;53
}54intmain()
68if(dfs(bigsta)) printf("
yes\n");
69else printf("
no\n");
70}71return0;
72 }
銀河之星 記憶化搜尋 9點染色
problem 3 銀河之星 galaxy.cpp c pas 資料組數不超過10.這題就是記憶化搜尋 9點染色減少狀態,map記憶化 b i j k 表示棋子可否從k方向到 i,j include include include include include include include in...
記憶化搜尋
演算法上依然是搜尋的流程,但是搜尋到的一些解用 動態規劃 的那種思想和模式作一些儲存。一般說來,動態規劃總要遍歷所有的狀態,而搜尋可以排除一些無效狀態。更重要的是搜尋還可以剪枝,可能剪去大量不必要的狀態,因此在空間開銷上往往比動態規劃要低很多。記憶化演算法在求解的時候還是按著自頂向下的順序,但是每求...
記憶化搜尋
記憶化搜尋 演算法上依然是搜尋的流程,但是搜尋到的一些解用動態規劃的那種思想和模式作一些儲存。記憶化演算法在求解的時候還是按著自頂向下的順序,但是每求解乙個狀態,就將它的解儲存下來,以後再次遇到這個狀態的時候,就不必重新求解了。例1.題目描述 給從左至右排好隊的小朋友們分糖果,要求 1.每個小朋友都...