第一周 枚举
1.完美立方(循环条件优化)
2.生理周期(循环跳步优化)
3.POJ1013称硬币
4.POJ1222熄灯问题(局部分析)(利用二进制枚举)
例题四也就是熄灯问题值得反复学习一下,下面附上本人的AC代码= =,其实和老师的差不多,打一遍看看哪部分没有理解,也耗费了很多时间,位运算脑子有点转不过来
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
//防止越界就不设5了
int map[6]; //输入
int ing[6]; //正在处理
int ans[6]; //输出
int getnum(int num, int n) // num == 输入的数字, n == 要取的位数
{
return (num >> n) & 1;
}
void change(int &num, int n)
{
num ^= (1 << n);
return;
}
void setnum(int &num, int n, int in) // in == 要设置的数字
{
if(in)
num |= (1 << n);
else
num &= ~(1 << n);
return;
}
void outans(int n)
{
cout << "PUZZLE #" << n << endl;
for(int i = 0; i < 5; i++)
for(int j = 0; j < 6; j++)
{
cout << getnum(ans[i], j);
if(j == 5)
cout << endl;
else
cout << " ";
}
return;
}
int main()
{
int n, temp;
cin >> n;
for(int puzzle = 1; puzzle <= n; puzzle++)
{
int i, j, k;
//读入数据
for(i = 0; i < 5; i++)
for(j = 0; j < 6; j++)
{
cin >> temp;
setnum(map[i], j, temp);
}
for(i = 0; i < 64; i++)
{
int swit = i;
memcpy(ing, map, sizeof(map));
for(j = 0; j < 5; j++)
{
ans[j] = swit;
for(k = 0; k < 6; k++)
{
if(getnum(swit, k)) // 改变本行的数据
{
if(k > 0)
change(ing[j], k - 1);
if(k < 5)
change(ing[j], k + 1);
change(ing[j], k);
}
}
if(j < 4) //改变下一行的数据
ing[j + 1] ^= swit;
swit = ing[j];
}
if(ing[4] == 0)
{
outans(puzzle);
break;
}
}
}
return 0;
}