Extended Lights Out--ZOJ 1354

位运算解决谜题
本文介绍了一种使用位运算和递归搜索解决特定谜题的方法。通过定义一系列按位操作和状态转移,实现了对谜题的有效求解。文章提供了一个完整的C++程序示例,展示了如何初始化谜题状态、进行搜索并输出解。

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 }

 

转载于:https://www.cnblogs.com/yongze103/archive/2010/04/25/1720632.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值