题目:http://poj.org/problem?id=2965
和1753很类似,也是一个4*4的棋盘,通过开关锁,来使得棋盘上所有的锁都是OPEN,当打开一个锁的时候,会同时修改行和列锁的状态。分析:
(1)同样的,每个格子的锁只要开一次就够了,因为如果打开两次,等于没有打开。
(2)棋盘的状态跟开锁的顺序没有关系,只跟开锁的个数和位置有关系。
如果用0-1表示开不开一个锁,那么相当于求棋盘格子的01序列,总共有2^16种可能性,因此可以用枚举的方法。方式和1753很类似(见上一个博客),但是多加了一个path用于记录开关锁的位置。代码如下:
#include <stdio.h>
#define ONLINE
void online()
{
#ifdef ONLINE
#else
freopen("2965.in", "r", stdin);
freopen("2965.out", "w", stdout);
#endif
}
int map = 0;
const int END = 0X0000;
const int SIZE = 16;
const int state[SIZE] = {
0xF888, 0xF444, 0xF222, 0xF111,
0x8F88, 0x4F44, 0x2F22, 0x1F11,
0x88F8, 0x44F4, 0x22F2, 0x11F1,
0x888F, 0x444F, 0x222F, 0x111F
};
int result = 17;
int path=0;//用于记录路径
void read()
{
char c;
for (int i=0; i < SIZE; i++)
{
c = getchar();
if (c == '+')
{
map = map << 1;
map = map ^ 1;
}//end if
else if (c == '-')
{
map = map << 1;
}
else{
i --;
}//end else
}//end for
}
void search(int idx, int step, int p)
{
if (step >= result)
{
return;
}
if (idx >= SIZE)
{
if (map == END && step < result)
{
result = step;
path = p;
}//end if
return;
}
p = p << 1;
p = p^1;
map = map ^ state[idx];
search(idx+1, step +1, p);
map = map^state[idx];
p = p >> 1;
p = p << 1;
search(idx+1, step, p);
p = p >>1;
}
void print()
{
printf("%d\n", result);
//打印步骤
int bit = 15;
for (int i=1; i <=4; i ++)
{
for (int j=1; j <= 4; j ++)
{
if ((path >> bit)&1 == 1)
{
printf("%d %d\n", i, j);
}// end if
bit --;
}//end for
}//end for
}
int main()
{
online();
read();
search(0, 0, 0);
print();
return 0;
}
运行结果如下:
2965 | Accepted | 160K | 63MS | C++ | 1430B | 2011-07-29 22:17:01 |