Extended Lights Out--ZOJ 1354
1、解题思路:贪心、枚举、位运算。
2、注意事项:
位运算:注意^ 、^、<<;
递归:注意剪枝;
3、实现方法:
1 #include <iostream>
2 using namespace std;
3 #define ROW 5
4 #define COL 6
5
6 bool isOK;
7
8 int press[30]={
9 06040000000,07020000000,03410000000,01604000000,0702000000,0301000000,
10 04060400000,02070200000,01034100000,0416040000, 0207020000,0103010000,
11 040604000, 020702000, 010341000, 04160400, 02070200, 01030100,
12 0406040, 0207020, 0103410, 041604, 020702, 010301,
13 04060, 02070, 01034, 0416, 0207, 0103
14 };
15
16 int pressing[30]={
17 04000000000,02000000000,01000000000,0400000000,0200000000,0100000000,
18 040000000, 020000000, 010000000, 04000000, 02000000, 01000000,
19 0400000, 0200000, 0100000, 040000, 020000, 010000,
20 04000, 02000, 01000, 0400, 0200, 0100,
21 040, 020, 010, 04, 02, 01
22 };
23
24 int Init()
25 {
26 int i,j,n,data=0;
27 for(i=0;i<ROW;i++)
28 {
29 for(j=0;j<COL;j++ )
30 {
31 cin >> n;
32 data <<= 1;
33 data += n;
34 }
35 }
36 return data;
37 }
38
39 void Print(int data)
40 {
41 int i,j;
42 for(i=0;i<ROW;i++ )
43 {
44 for(j=0;j<COL;j++)
45 {
46 if( (data & pressing[i*COL+j]) == 0 )
47 cout << 0;
48 else
49 cout << 1;
50 if( j<COL-1 )
51 cout << ' ';
52 }
53 cout << endl;
54 }
55 }
56
57 void Search(int data,int preState)
58 {
59 int i,j;
60 for(i=1;i<ROW;i++)
61 {
62 for(j=0;j<COL;j++)
63 {
64 if( (data & pressing[(i-1)*COL+j]) != 0 )
65 {
66 data ^= press[i*COL+j];
67 preState += pressing[i*COL+j];
68 }
69 }
70 }
71 if(data==0)
72 {
73 Print(preState);
74 isOK = true;
75 }
76 }
77
78 void Do(int data,int x,int preState)
79 {
80 //找到解
81 if( isOK )
82 {
83 return;
84 }
85 Search(data,preState);
86 //遍历完第一行
87 if( x == COL )
88 return;
89 Do(data,x+1,preState);
90 Do(data^press[x],x+1,preState^pressing[x]);
91 }
92
93 int main()
94 {
95 int i,m;
96 cin >> m;
97 int data;
98 for(i=1;i<=m;i++)
99 {
100 cout<<"PUZZLE #"<<i<<endl;
101 data = Init();
102 isOK = false;
103 Do(data,0,0);
104 }
105 return 0;
106 }