算法提高 开灯游戏


 算法提高 开灯游戏  
时间限制:1.0s   内存限制:256.0MB
    
问题描述
  有9盏灯与9个开关,编号都是1~9。

  每个开关能控制若干盏灯,按下一次会改变其控制的灯的状态(亮的变成不亮,不亮变成亮的)。

  具体如下:

  第一个开关控制第二,第四盏灯;

  第二个开关控制第一,第三,第五盏灯;

  第三个开关控制第二,第六盏灯;

  第四个开关控制第一,第五,第七盏灯;

  第五个开关控制第二,第四,第六,第八盏灯;

  第六个开关控制第三,第五,第九盏灯;

  第七个开关控制第四,第八盏灯;

  第八个开关控制第五,第七,第九盏灯;

  第九个开关控制第六,第八盏灯。

  开始时所有灯都是熄灭的,开关是关闭着的。要求按下若干开关后,使得只有4盏灯亮着。
输出格式
  输出所有可能的方案,每行一个方案,每一行有9个字符,从左往右第i个字符表示第i个开关的状态("0"表示关闭,"1"表示打开),按字典序输出。下面的样例输出只是部分方案。
样例输出
000001011
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;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值