題意:乙個4×4的棋盤,每個格仔放著乙個棋子。棋子一面是白色,一面是黑色。一次操作可以將某乙個格仔以及上下左右共5個格仔的棋子都翻過來,即白色變黑色,黑色變白色。現在給出一種棋盤狀態,問最少需要幾次操作可以將棋盤全部變為同種顏色。
輸入:sample input
bwwbsample outputbbwb
bwwb
bwww
4
典型的廣搜題目:這裡把這道題的收穫寫在這裡,以便以後回顧:
首先是要明白spfa演算法:
演算法的流程其實與分層遍歷二叉樹的**差不多。
if (0 == t || (1<<16) - 1 == t) return 0;
memset(rec, 0, sizeof(rec)); memset(step, 0, sizeof(step));
queueq; q.push(t); step[t] = 0; rec[t] = 1;
while (!q.empty())
}} return -1;
flip的實現
inline void set(int &m, int i, int j)
inline void clr(int &m, int i, int j)
inline bool test(int &m, int i, int j)
inline void rever(int &m, int i, int j)
inline bool range(int i, int j)
void flip(int &m, int i, int j)
, , , };
for (int k = 0; k < 4; ++k)
}
後來發現對某一位取反,只要 n ^= (1 << i );就可以了。
實際上,如果對於0,1,兩位取異或則是 n ^= 3
那麼在翻動的過程中,翻動第乙個棋子時,應該與19取異或。
每一位應該與哪個數取異或可以由以下程式得到
#includeint main(void)
, , , };
int i, j, k, n, v;
int x, y;
for (i = 0; i < 16; ++i)
}printf("%d,", n);
}return 0;
}
那麼在在翻某一位時,可以把**更改如下:
q[++tail] = t; rec[t] = 1;
while (head != tail)
}} return -1;
輸入的處理
如果分開輸入,那麼輸入之後,還要把字串接起來,有沒有什麼辦法直接得到整個字串,偶然得到下面這個方法比較好使
char str[15];
scanf("%s%s%s%s", str, str + 4, str + 8, str + 12);
輸入之後,你再輸出str試試
**寫得一般,湊合著看吧,我比較喜歡把**寫得短一點。
#include#include#includeint flip = ;
char rec[1<<16];
int step[1<<16];
int q[1<<18];
int bfs(int t)
} }return -1;
}char str[40];
static int getn(char *s)
return n;
}int main(void)
POJ1753 棋盤翻轉(位壓縮 廣度優先搜尋)
題目大意 有乙個4 4的方格,每個方格中放一粒棋子,這個棋子一面是白色,一面是黑色。遊戲規則為每次任選16顆中的一顆,把選中的這顆以及它四周的棋子一併反過來,當所有的棋子都是同乙個顏色朝上時,遊戲就完成了。現在給定乙個初始狀態,要求輸出能夠完成遊戲所需翻轉的最小次數,如果初始狀態已經達到要求輸出0。...
poj 1753 位壓縮 搜尋
題意 有乙個4 4的方格,每個方格中放一粒棋子,這個棋子一面是白色,一面是黑色。遊戲規則為每次任選16顆中的一顆,把選中的這顆以及它四周的棋子一併反過來,當所有的棋子都是同乙個顏色朝上時,遊戲就完成了。現在給定乙個初始狀態,要求輸出能夠完成遊戲所需翻轉的最小次數,如果初始狀態已經達到要求輸出0。如果...
poj1753 搜尋,列舉法
1 2014.3.1 2 poj175334 5 題意 6 給你乙個4 4的黑白棋盤,通過翻棋子使棋盤變為全白或全黑,7 以下 翻乙個位置 皆指翻著個位置和它周圍的四個棋子。8 翻子時四周的四個棋子如果存在的話顏色也會跟著改變。9 問最少需要多少步可以使棋盤變為一種顏色。10 11 思路 12 每一...