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;

}

 

 

 

 

你可能感兴趣的:(poj)