算法提高 开灯游戏
时间限制:1.0s 内存限制:256.0MB
问题描述
有9盏灯与9个开关,编号都是1~9。
每个开关能控制若干盏灯,按下一次会改变其控制的灯的状态(亮的变成不亮,不亮变成亮的)。
具体如下:
第一个开关控制第二,第四盏灯;
第二个开关控制第一,第三,第五盏灯;
第三个开关控制第二,第六盏灯;
第四个开关控制第一,第五,第七盏灯;
第五个开关控制第二,第四,第六,第八盏灯;
第六个开关控制第三,第五,第九盏灯;
第七个开关控制第四,第八盏灯;
第八个开关控制第五,第七,第九盏灯;
第九个开关控制第六,第八盏灯。
开始时所有灯都是熄灭的,开关是关闭着的。要求按下若干开关后,使得只有4盏灯亮着。
每个开关能控制若干盏灯,按下一次会改变其控制的灯的状态(亮的变成不亮,不亮变成亮的)。
具体如下:
第一个开关控制第二,第四盏灯;
第二个开关控制第一,第三,第五盏灯;
第三个开关控制第二,第六盏灯;
第四个开关控制第一,第五,第七盏灯;
第五个开关控制第二,第四,第六,第八盏灯;
第六个开关控制第三,第五,第九盏灯;
第七个开关控制第四,第八盏灯;
第八个开关控制第五,第七,第九盏灯;
第九个开关控制第六,第八盏灯。
开始时所有灯都是熄灭的,开关是关闭着的。要求按下若干开关后,使得只有4盏灯亮着。
输出格式
输出所有可能的方案,每行一个方案,每一行有9个字符,从左往右第i个字符表示第i个开关的状态("0"表示关闭,"1"表示打开),按字典序输出。下面的样例输出只是部分方案。
样例输出
000001011
000001110
000001111
000001110
000001111
思路分析:我的做法是暴力枚举。定义9个开关变量,设定两种不同的状态0和1(代表关、开)。枚举每一种可能的情况,并进行判断。数据比较小,所以方案可行,就是代码比较繁琐。
另外一种思路是用字符串每次加1的过程:从000000000一直加到111111111,写一个字符串模拟大数加法的过程,实质也是枚举每一种情况的过程。
不知道这道题位运算能不能做,我对位运算的掌握不是很熟练。
#include <cstdio>
#include <string>
using namespace std;
int l1, l2, l3, l4, l5, l6, l7, l8, l9;
int a[10] = { 0 };
void judge() {
if( l1 ) { a[2] = ( a[2] + 1 ) % 2; a[4] = ( a[4] + 1 ) % 2; }
if( l2 ) { a[1] = ( a[1] + 1 ) % 2; a[3] = ( a[3] + 1 ) % 2; a[5] = ( a[5] + 1 ) % 2; }
if( l3 ) { a[2] = ( a[2] + 1 ) % 2; a[6] = ( a[6] + 1 ) % 2; }
if( l4 ) { a[1] = ( a[1] + 1 ) % 2; a[5] = ( a[5] + 1 ) % 2; a[7] = ( a[7] + 1 ) % 2; }
if( l5 ) { a[2] = ( a[2] + 1 ) % 2; a[4] = ( a[4] + 1 ) % 2; a[6] = ( a[6] + 1 ) % 2; a[8] = ( a[8] + 1 ) % 2; }
if( l6 ) { a[3] = ( a[3] + 1 ) % 2; a[5] = ( a[5] + 1 ) % 2; a[9] = ( a[9] + 1 ) % 2; }
if( l7 ) { a[4] = ( a[4] + 1 ) % 2; a[8] = ( a[8] + 1 ) % 2; }
if( l8 ) { a[5] = ( a[5] + 1 ) % 2; a[7] = ( a[7] + 1 ) % 2; a[9] = ( a[9] + 1 ) % 2; }
if( l9 ) { a[6] = ( a[6] + 1 ) % 2; a[8] = ( a[8] + 1 ) % 2; }
int cnt = 0;
for( int i = 1; i <= 9; i++ ) {
if( a[i] ) cnt++;
}
if( cnt == 4 ) {
printf( "%d%d%d%d%d%d%d%d%d\n", l1, l2, l3, l4, l5, l6, l7, l8, l9 );
}
}
int main() {
for( l1 = 0; l1 <= 1; l1++ )
for( l2 = 0; l2 <= 1; l2++ )
for( l3 = 0; l3 <= 1; l3++ )
for( l4 = 0; l4 <= 1; l4++ )
for( l5 = 0; l5 <= 1; l5++ )
for( l6 = 0; l6 <= 1; l6++ )
for( l7 = 0; l7 <= 1; l7++ )
for( l8 = 0; l8 <= 1; l8++ )
for( l9 = 0; l9 <= 1; l9++ ) {
fill( a, a + 10, 0 );
judge();
}
return 0;
}