您的位置:首页 > 运维架构

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

2017-10-04 19:58 330 查看
已知灯的情况。

枚举第一行开关的情况。

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

更进一步的我们确定这么一种现象:如果知道(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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: