POJ 2965 The Pilots Brothers' refrigerator

题意: 4*4的矩阵, “+”表示关闭, “—”表示开启, 当改变一个位置的时候,其所在的行和列都会取反,求最少需要多少步能将其全部置为“-”。

思路:暴力枚举+BFS。 先写一个异或的数组,然后依次异或。 其中用pt 保存路径。

 

10957265 NY_lv10 2965 Accepted 1240K 938MS C++ 1103B 2012-10-26 11:24:33

 

View Code
#include <iostream>
#include <queue>
using namespace std;

int chang[] = {
    63624, 62532, 61986, 61713,
    36744, 20292, 12066, 7953,
    35064, 17652, 8946, 4593,
    34959, 17487,8751, 4383}; 

struct point 
{
    int x;  //保存前驱
    int y;  //改变了哪个点
};


bool used[65536];   //数组65535 运行错误。。。⊙﹏⊙b汗
int step[65536];

int path[20];
point pt[65536];

int main()
{
    queue<int> que;
    int id, n;
    char ch;
    int i, j;
    id = 0;
    for (i=0; i<16; i++)
    {
        id <<= 1;
        cin>>ch;
        if (ch == '+')
            id += 1;
    }
    memset(used, false, sizeof(used));
    step[id] = 0;
    pt[id].x = id;
    n = id;
    used[id] = true;
    que.push(id);
    
    while (!que.empty())
    {
        int tmp = que.front();
        que.pop();
        for (i=0; i<16; i++)
        {
            id = tmp;
            id ^= chang[i];
            if (!used[id])
            {
                used[id] = true;
                que.push(id);
                step[id] = step[tmp] + 1;
                pt[id].x = tmp;
                pt[id].y = i;
                
            }
            if (id == 0)
                goto L;
        }
    }
L:
    cout<<step[0]<<endl;
    j = 0;
    while (id != n)
    {
        path[j++] = pt[id].y;
        id = pt[id].x;
    }
    for (i=j-1; i>=0; i--)
        cout<<path[i]/4+1<<" "<<path[i] % 4+1<<endl;
    return 0;
}

 

 

 

 

posted @ 2012-10-26 11:56  旅行的蜗牛  阅读(234)  评论(0编辑  收藏  举报