1. 程式人生 > >#112-【廣搜】程式龍的遊戲

#112-【廣搜】程式龍的遊戲

題目描述

在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;
}