POJ-2965 The Pilots Brothers' refrigerator (枚举)

题目传送门

题意

  给定一个\(4\times 4\)的棋盘,每个格子有开启和关闭两种状态,每次选择一个格子,同时改变当前格子所处的行和列的所有状态,问需要几步才能将所有格子的状态变成开启,并输出每次选择的格子。

思路

  本题与POJ-1753Flip Game 枚举类似,由于只有16个格子,我们可以用二进制状态存下当前的状态,通过对二进制不同位上的值来反应对映格子的状态,值得注意的是,如果不使用状态压缩的做法,可能会出现超时的情况。

参考代码

点此展开

//Author:Daneii
#include<iostream>
#include<queue>

using namespace std;

#define in(x) scanf("%d",&x)
#define lin(x) scanf("%lld",&x)
#define din(x) scanf("%lf",&x)

typedef long long ll;
typedef long double ld;
typedef pair<int,int> PII;

const int N=4;

int hh=0,tt=0;
struct node
{
    int state;
    int pos;
    int step;
    int pre;
}qs[1<<16+1];


bool used[1<<16+1];

void show(node cur)
{
    if(cur.pre==-1)
        return ;
    show(qs[cur.pre]);
    cout<<cur.pos/4+1<<' '<<cur.pos%4+1<<endl;//输出选取的点
}

int change(int s,int pos)
{
    int cur=pos/4;//确定在哪一行
    cur*=4;
    for(int i=cur;i<cur+4;i++)//更新行
    {
        s^=(1<<i);
    }
    cur=pos%4;
    for(int i=0;i<16;i+=4)//更新列
    {
        s^=(1<<(i+cur));
    }
    s^=(1<<pos);//翻转自己本身那个点
    return s;
}

int main()
{
    #ifdef LOCAL
    freopen("D:/VSCodeField/C_Practice/.input/a.in", "r", stdin);
    freopen("D:/VSCodeField/C_Practice/.input/a.out", "w", stdout);
    #endif

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    node st;
    st.step=0;
    st.pre=-1;
    st.state=0;

    for(int i=0;i<16;i++)
    {
        char c;
        cin>>c;
        if(c=='+')
            st.state|=(1<<i);
    } 

    qs[tt++]=st;
    used[st.state]=true;

    while(hh<tt)
    {
        node tmp=qs[hh];

        if(tmp.state==0)
        {
            cout<<tmp.step<<endl;
            show(tmp);
            return 0;
        }
        for(int i=0;i<16;i++)
        {
            node ns;
            ns.state=change(tmp.state,i);
            if(!used[ns.state])
            {
                ns.pre=hh;//记录前驱
                ns.pos=i;//记录当前在哪里修改的
                ns.step=tmp.step+1;//记录步数
                qs[tt++]=ns;
                used[ns.state]=true;
            }
        }
         hh++;
    }     
    

    return 0;
}
posted @ 2021-08-11 15:11  Daneii  阅读(32)  评论(0)    收藏  举报