1、问题:有一个由按钮组成的矩阵,其中每行6个按钮,共5行,每个按钮的位置对应一盏灯,按下一个按钮后,上下左右的灯的状态就会翻转。
输入:
第一行是一个正整数N,表示需要解决的案例数
每个案例由5行组成,每一行包括6个数字,这些数字以空格相间,是0或者1。
输出:
对于每个案例,首先输出一行字符串“PUZZLE #m”,其中m是该案例的序号,
接着按照案例的输入格式输出5行,1表示按钮按下,0表示不需要按下按钮,以空格相间。
思路:
对第一行中的每盏灯,按下第二行对应的按钮,就可以将第一行的灯全部熄灭,
如此这样按照1-5行的顺序,重复下去,就可以将1,2,3,4行全部按灭,如果此时第5行的灯也是灭的,那么就是问题的解,否则,这种按法不是想要的解。
上面没有成功的话,则需要重新从第一行开始按,第一行的按法总共有2*5=32,所以在第一行的局部按法之上,总共可以进行32次尝试,得到问题的解。
1 #include <iostream> 2 #include <string> 3 #include <cstring> 4 #include <memory> 5 using namespace std; 6 7 int GetBit(char c, int i){ 8 //取c的第i位 9 return (c >> i) & 1 ; 10 } 11 12 void SetBit(char & c, int i, int v){ 13 //设置c的第i位为v 14 if(v){ 15 c |= (1 << i); 16 } 17 else{ 18 c &= ~(1 << i); 19 } 20 } 21 22 void Flip(char & c, int i){ 23 //将c的第i位取反 24 c ^= (1 << i); 25 } 26 27 void OutputResult(int t, char result[]){ 28 cout << "PUZZLE # " << t << endl; 29 for(int i = 0; i < 5; i++){ 30 for(int j = 0; j < 6; j++){ 31 cout << GetBit(result[i],j) ; 32 if(j < 5){ 33 cout << " " ; 34 } 35 } 36 cout << endl ; 37 } 38 } 39 40 int main() 41 { 42 char oriLights[5] ; 43 char lights[5] ; 44 char result[5] ; 45 char switchs ; 46 int T ; 47 cout<<"The results num = " << endl; 48 cin >> T ; 49 for(int t=1; t <= T; t++){ 50 memset(oriLights,0,sizeof(oriLights)); 51 for(int i = 0; i < 5; i++){ 52 cout <<"Please Input the lights[j]"<<endl; 53 for(int j = 0; j < 6; j++){ 54 int s; 55 cin >> s; 56 SetBit(oriLights[i],j,s); 57 } 58 } 59 60 for(int n=0; n<64; n++){ 61 memcpy(lights,oriLights,sizeof(oriLights)); 62 switchs = n; 63 // 每一个局部,第一行的开关方案就是该n,同时,在循环中switchs 也表示第i行的开关状态 64 //第一行的开关选择,不是为了使得第一行灯为0,而是为了改变灯的状态,构造一个局部环境,产生一个局部条件。 65 for(int i=0; i<5; i++){ 66 result[i] = switchs;//第i行开关方案 ,第0行的方案为n值,符合解题思路。result[0] = n; 67 //首先要求出,第一行灯的状态,第一行的switch,改变本行的状态,它决定第二行的开关开法,使得第一行全灭。 68 //下一次第二行开关拨发已经固定了,要求出第二行灯的状态,它决定第三行的开关开法,使得第二行全灭。 69 for(int j=0; j<6; j++){ 70 if(GetBit(switchs,j)){ 71 if(j>0) 72 Flip(lights[i],j-1); 73 if(j<5) 74 Flip(lights[i],j+1); 75 Flip(lights[i],j); 76 } 77 } 78 //本行状态变化,决定下一行的switch 79 if(i<4) 80 lights[i+1] ^= switchs; //下一行灯的状态发生改变 81 82 switchs = lights[i]; //预先求出下一行的switchs 83 } 84 if(lights[4] == 0){ 85 OutputResult(t,result); 86 break; 87 } 88 } 89 } 90 return 0; 91 system("pause"); 92 }
运行结果: