您的位置:首页 > 其它

Enum:EXTENDED LIGHTS OUT(POJ 1222)

2016-01-24 19:44 441 查看
                


                    亮灯

  题目大意:有一个5*6的灯组,按一盏灯会让其他上下左右4栈和他自己灯变为原来相反的状态,要怎么按才会把所有的灯都按灭?

  3279翻版题目,不多说,另外这一题还可以用其他方法,比如DFS,BFS,不过这些都挺慢的,月还有一个特别厉害的方法,高斯消元法,等我以后再来写

  

#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

static int map[5][6], store[5][6], flip[5][6];
static int dirx[4] = { -1, 0, 0,  1 };
static int diry[4] = { 0, -1, 0, 0 };

int solve(void);
int get_light(const int, const int);

int main(void)
{
int sum_of_martrix, ans, res;
scanf("%d", &sum_of_martrix);

for (int k = 1; k <= sum_of_martrix;k++)
{
ans = INT_MAX;
for (int i = 0; i < 5; i++)//Read Gragh
for (int j = 0; j < 6; j++)
scanf("%d", &map[i][j]);

for (int i = 0; i < 1 << 6; i++)
{
memset(flip, 0, sizeof(flip));
for (int j = 0; j < 6; j++)
flip[0][5 - j] = (i >> j) & 1;
res = solve();
if (res < ans)
{
ans = res;
memcpy(store, flip, sizeof(flip));
}
}
printf("PUZZLE #%d\n", k);
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 6; j++)
printf("%d ", store[i][j]);
printf("\n");
}
}
return EXIT_SUCCESS;
}

int solve(void)
{
int ans = 0;
for (int i = 1; i < 5; i++)
for (int j = 0; j < 6; j++)
flip[i][j] = get_light(i - 1, j);//如果这一列的上一行是亮灯,那么必须按下这盏灯

for (int j = 0; j < 6; j++)
{
if (get_light(4, j) == 1)//看最后一行的灯的情况是否全部灯都灭了
return INT_MAX;
}

for (int i = 0; i < 5; i++)
for (int j = 0; j < 6; j++)
ans += flip[i][j];
return ans;
}

int get_light(const int y, const int x)
{
int dx, dy, sum = map[y][x];

for (int i = 0; i < 4; i++)
{
dx = x + dirx[i]; dy = y + diry[i];
if (0 <= dx && dx < 6 && 0 <= dy && dy < 5)
sum += flip[dy][dx];
}
return sum % 2;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: