1 #include <iostream> 2 #include <cstring> //memset(),memcpy头文件 3 using namespace std; 4 5 //获取第j位 6 int Getbit(int num,int j) 7 { 8 return (num >> j)&1; 9 } 10 //设置第j位 11 void Setbit(char& num,int j, int s) 12 { 13 if(s) 14 num |= (1 << j); 15 else 16 num &= ~(1 << j); 17 } 18 //反转第j位 19 void Flipbit(char& num,int j) 20 { 21 num ^= (1 << j); 22 } 23 24 int main(int argc,char* argv[]) 25 { 26 char orilight[5];//原始灯状态 27 char curlight[5];//当前灯的状态 28 char result[5]; //结果 29 int switchs; //开关状态 30 bool flag = false;//判断是否有结果 31 32 //初始化原始灯状态 33 memset(orilight,0,sizeof(orilight)); 34 for(int i = 0;i < 5;++i) 35 for(int j = 0;j < 6;++j) 36 { 37 int single; 38 cin >> single; 39 Setbit(orilight[i],j,single); 40 } 41 //确定结果 42 for(int n = 0;n < 64;++n) 43 { 44 switchs = n; 45 memcpy(curlight,orilight,sizeof(orilight));//每执行一次枚举就将原始灯的状态存到当前灯矩阵中 46 //以保证每次测试结果都不会改变原始状态 47 //处理每一行灯的状态 48 for(int i = 0;i < 5;++i) 49 { 50 result[i] = switchs; 51 for(int j = 0;j < 6;++j) 52 { 53 if(Getbit(switchs,j)) 54 { 55 if(j > 0) 56 Flipbit(curlight[i],j - 1); 57 Flipbit(curlight[i],j); 58 if(j < 5) 59 Flipbit(curlight[i],j+1); 60 } 61 } 62 //处理第i+1行灯的状态 63 if(j < 4) 64 curlight[i+1] ^= switchs; 65 switchs = curlight[i]; 66 } 67 //当第五行的灯熄灭时,找到结果 68 if(curlight[4] == 0) 69 { 70 flag = true; 71 break; 72 } 73 } 74 if(flag) 75 { 76 for(int i = 0;i < 5;++i) 77 { 78 for(int j = 0;j < 6;++j) 79 { 80 cout << Getbit(result[i],j) << " "; 81 } 82 cout << endl; 83 } 84 } 85 else 86 cout << "no anwser" << endl; 87 88 return 0; 89 }
补充:对于所需要的枚举次数,我们可以这样计算:因为我们只需要枚举第一行的灯的状态,而第一行有6盏灯,所以全排列就是26种,即我们只需枚举64次。
当然,我们也可以枚举更少的次数,也就是只枚举32次(25),按列来枚举,这种方法可以考虑使用大小为6的char数组,每个数组存一列,其他过程
如按行枚举。