9801 黑白棋遊戲

2021-09-29 18:57:18 字數 2629 閱讀 9506

time limit: 3 second

memory limit: 2 mb

黑白棋遊戲的棋盤由4*4方格陣列構成。棋盤的每一方格中放有1枚棋子,共有8枚白棋子和8枚黑棋子。這16枚棋子的每一種放置方案都構成乙個遊戲狀態。在棋盤上擁有1條公共邊的2個方格稱為相鄰方格。乙個方格最多可有4個相鄰方格。在玩黑白棋遊戲時,每一步可將任何2個相鄰方格中棋子互換位置。對於給定的初始遊戲狀態和目標遊戲狀態,程式設計計算從初始遊戲狀態變化到目標遊戲狀態的最短著棋序列。

共有8行。前四行是初始遊戲狀態,後四行是目標遊戲狀態。每行4個數分別表示該行放置的棋子顏色,「0」表示白棋,「1」表示黑棋。

第一行是著棋步數n,接下來n行,每行4個數分別表示該步交換棋子的兩個相鄰方格的位置。例如abcd表示將棋盤上(a,b)處的棋子與(c,d)處的棋子換位。

1111

0000

1110

0010

1010

0101

1010

0101

4

1222

1424

3242

4344

【題解】

這題的難點在狀態的判重上。需要用到二進位制來表示棋子的狀態。

首先,預處理出2^1->2^16;存在乙個陣列中。需要的時候直接訪問即可。

然後把4行的棋子狀態轉變為一行。

如輸入樣例 起始狀態為 1111000011100010;一共16個字元。

注意一開始的時候在字串前加個空格。這樣這串字元就從字串的下標1開始了。

然後for (int i = 1;i <= 16;i++) sum +=two_n[i]*(s[i]-'0');

這樣就把「二進位制轉化成10進製了」但注意真正的二進位制轉10進製需要逆序 且是從2^0開始的。

但我們只需要用二進位制的思想儲存狀態就可以了。

然後bo[sum] = true,標記這個狀態已經出現過。

然後進行廣搜。

在廣搜的時候不要把這段「十進位制」轉化成字串。而是直接在這個「十進位制」上進行操作。

我們在搜的時候只要考慮兩個變換方向即向右和向下。因為向左和向右會重複。

同時我們要判斷兩個棋子顏色是否不同,如果顏色相同則移動毫無意義。

然後for(int i = 1;i <= 16;i++)

然後是變換的原理

比如 11100000000

我們要把第4個0變成1,只要加上2^4就可以了。

我們要把第2個1變成0,只要減去2^2就可以了。

具體的操作請看**

【**】

#include #include #include using namespace std;

const int maxdl = 100000;

struct ss

;int two_n[17],f,t,team[maxdl],step[maxdl],pre[maxdl];

string s1,s2;

bool panchong[131079*2] = ;

ss d_step[maxdl];

void input_data(string & s1) }

void init() //先預處理出2的1次方到2的16次方

void output_ans(int temp) //用於遞迴輸出方案。

void get_ans()

panchong[f] = true; //標記這個狀態已經找過

while (head != tail)

; //用於「把十進位制換成二進位制」

for (int i = 1;i <= 16;i++)

if ( (ff & two_n[i]) > 0) //如果之前存過2^i次方,在這個偽10進製轉換成2進製後

//倒數第i+1位確實會變成1.所以和2^i進行與操作,如果這個位置上有棋子,最後結果會是大於0的。

//比如有0011這樣的情況。第3,4位為1,我們轉換成的偽十進位制是24;

//之後我們要把這個棋子資訊存進bo陣列中

//我們列舉i,i到了3,用2^3和24進行與運算

//2^3的二進位制是1000

//24的二進位制是11000 ,可以看到第4位都是1,所以我們判斷i=3時,bo[i] = 1(true);

//再列舉到4時

//2^4的二進位制是10000

//24的二進位制是11000 ,可以看到第5位都是1,所以我們判斷i=4時,bo[i] = 1(true);

//這種雖然和二進位制轉10進製的正確做法不同,但可以用這種「錯誤」的方法來儲存狀態

//並且在用位運算進行「壓縮」和「解壓」

//還有變換的例子。

//還是上面的0011

//偽十進位制為24;

//如果我們想把第3個1變成0就減去2^3.

//就變成了16;

//再用偽方法轉換成二進位制。就變成0001了。

bo[i] = true;

for (int i = 1;i <= 16;i++)

}

}}

if ( (i % 4) !=0) //如果不是最右邊的數字 } }

}}

}}int main()

黑白棋遊戲

黑白棋遊戲 time limit 10000ms memory limit 65536k total submit 9 accepted 5 case time limit 1000ms description 問題描述 黑白棋遊戲的棋盤由4 4方格陣列構成。棋盤的每一方格中放有1枚棋子,共有8枚白...

黑白棋遊戲

用c 封裝了一下,只完成了乙個雛形,有很多功能沒有新增上,但 的行數已經縮短了很多了。include include include includeusing namespace std class chess int counter 計數器,計算棋子個數 const friend void dra...

黑白棋遊戲

include include using namespace std char e 30 30 int a 30 30 int c 30 int x 30 int y 30 intf int n,int sum int pos sum 2 n int cnt 0 int flag 0 int w ...