#112-【广搜】程序龙的游戏

题目描述

在oiclass,程序龙喜欢和小朋友们一起玩游戏,今天,他有想到了一个好玩的游戏。
游戏规则:每次点击一个小朋友,他和他的周围的小朋友都会改变状态(蹲下的变成了站起来的,站起来的变成了蹲下的)
我们将这个抽象成如下图所示的1*N的图。对于一个单元格,黑色表示小朋友是站起来的,反之,蹲下的小朋友是白色。Source表示初始状态,Target表示目标状态。
#112-【广搜】程序龙的游戏_第1张图片
 
现在程序龙有点偷懒,希望玩游戏的你算出初始状态到目标状态的最少点击数。

输入

第一行为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 
#include 

#define SIZE 1010

using namespace std;

struct node
{
	int st, dis;
};

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

 

你可能感兴趣的:(刷题,gdgzoi刷题)