【Openjudge, NOI, 枚举】1813熄灯问题

9 篇文章 0 订阅
5 篇文章 0 订阅

已知灯的情况。

枚举第一行开关的情况。

我们知道这么一种现象:上一行的灯可以由下一行的开关控制达到完全关闭的状态。

更进一步的我们确定这么一种现象:如果知道(1)第n行灯的情况,(2)第n-1行开关的状态,(3)第n行开关的状态。那么,如果想要让第n行的灯全部关闭,第n+1行的开关的状态是确定的。特殊的,第一行只需要知道本行的灯的情况和本行开关的状态。

所以,只需要枚举第一行开关的情况,然后更新灯的状态,之后,通过第一行灯的状态,更新第二行的开关,直到更新到最后一行的开关,此时,如果最后一行的灯也全部是灭掉的状态,即是我们所求的开关的情况。

代码中,用一个整数的低6位表示一行灯或者一行开关。

#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;

void set(int &l, int &s){
	s = l;
}
void change(int &l, int &s, int pos){
	// pos:0,灯和开关不在同一行;1:灯和开关在同一行;
	if (pos == 0){
		l = l ^ s;
	}
	if (pos == 1){
		int left, right, mid;
		left = s << 1;
		right = s >> 1;
		mid = s;
		mid = (left ^ right ^ mid) & 63;
		l = mid ^ l;
	}
}
void show(int *t){
	int i,j;
	for (i = 0; i < 5; i ++){
		for (j = 0; j < 6; j ++){
			cout << ( (t[i] >> j)& 1) << ' ';
		}
		cout << endl;
	}
}

int main()
{
	int lt[5] = {};
	int sw[5] = {};
	int i, j;
	int t;
	for (i = 0 ; i < 5; i ++){
		for (j = 0; j < 6; j ++){
			scanf("%d", &t);
			lt[i] += t << j;
		}
	}
	//枚举第一行开关的状态
	for (sw[0] = 0; sw[0] < 64; sw[0] ++){
		int tsw[5] = {};
		memcpy(tsw, sw, sizeof(sw));
		int tlt[5] = {};
		memcpy(tlt, lt, sizeof(lt));

		change(tlt[0], tsw[0], 1);
		change(tlt[1], tsw[0], 0);

		//根据第一行开关设定每一行开关
		for (i = 1; i < 5; i ++){
			set(tlt[i - 1], tsw[i]);
			change(tlt[i - 1], tsw[i], 0);
			change(tlt[i], tsw[i], 1);
			if (i != 4)
				change(tlt[i + 1], tsw[i], 0);
		}
		if (tlt[4] == 0){
			show(tsw);
			break;
		}
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值