#112-【廣搜】程式龍的遊戲
阿新 • • 發佈:2018-11-09
題目描述
在oiclass,程式龍喜歡和小朋友們一起玩遊戲,今天,他有想到了一個好玩的遊戲。
遊戲規則:每次點選一個小朋友,他和他的周圍的小朋友都會改變狀態(蹲下的變成了站起來的,站起來的變成了蹲下的)
我們將這個抽象成如下圖所示的1*N的圖。對於一個單元格,黑色表示小朋友是站起來的,反之,蹲下的小朋友是白色。Source表示初始狀態,Target表示目標狀態。
現在程式龍有點偷懶,希望玩遊戲的你算出初始狀態到目標狀態的最少點選數。
輸入
第一行為N表示小朋友的個數
第二行是初始狀態,有N個數,每個數不是0就是1.(0表示小朋友是蹲下的,1表示小朋友是站起來的)
第三行的結構跟第二行類似,表示目標狀態
輸出
一個數X,表示初始狀態到目標狀態的最少點選數。
如果無法到達目標,則請輸出"Boring"
樣例輸入
9 0 1 0 0 0 1 0 0 0 1 0 1 0 1 0 1 0 0
樣例輸出
2
提示
對於100%的資料,N<=10
廣搜加二進位制優化
#include <iostream> #include <queue> #define SIZE 1010 using namespace std; struct node { int st, dis; }; queue<node> q; int bits[11] = {0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512}; // 二進位制優化 bool visited[SIZE]; int main(void) { int st = 0, ed = 0, n, i, j, u, v, x; scanf("%d", &n); for (i = 1; i <= n; ++i) { scanf("%d", &x); if (x) { st |= bits[i]; } } for (i = 1; i <= n; ++i) { scanf("%d", &x); if (x) { ed |= bits[i]; } } if (st == ed) // 如果起點就是終點,無需操作 { printf("0"); return 0; } q.push({st, 0}); visited[st] = true; while (!q.empty()) { u = q.front().st; for (i = 1; i <= n; ++i) { v = u; for (j = max(i - 1, 1); j <= min(i + 1, n); ++j) { v ^= bits[j]; // 位異或操作符^的妙用 } if (v == ed) { printf("%d", q.front().dis + 1); return 0; } if (!visited[v]) { visited[v] = true; q.push({v, q.front().dis + 1}); } } q.pop(); } printf("Boring"); // 無解 return 0; }