The Pilots Brothers' refrigerator(POJ2965枚举)

~题目链接~

http://poj.org/problem?id=2965

输入

-+--
----
----
-+--

结果

6
1 1
1 3
1 4
4 1
4 3
4 4

1.BFS+位运算

自己写了一半天异或的代码,又长又不实用,提交还TLE(此在代码有 已被注释,如果有大牛可以改出来,希望帮助);后跟人家学了一招,很方便。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#define maxm 65535+10
#define maxn 4

using namespace std;

int ID[30] = {4383,8751,17487,34959,4593,8946,17652,35064,7953,12066,20292,36744,61713,61986,62532,63624};
int id=0,m=0,vis[1<<17];

struct node
{
    int data,num,step;
} cur;
struct path
{
    int x,pre;
}p[maxm<<2];

void f(int n)
{
    if(n)
    {
        f(p[n].pre);
        printf("%d %d
",4-p[n].x/4,4-p[n].x%4);
    }
}

void BFS()
{
    int i;
    cur.data=id;
    cur.num=0;
    cur.step=0;
    p[1].pre=0;
    queue<node>Q;
    Q.push(cur);
    while(!Q.empty())
    {
        if(Q.front().data==0)
        {
            printf("%d
",Q.front().step);
            f(Q.front().num);
            return;
        }
        for(i=15; i>=0; i--)
        {
            node a;
            //提交TLE的码码,有大牛在的话,求指教
            /*int j;
            a.data=Q.front().data^(1<<i);//此位点翻转
            j=i;
            while(j<12)//此位点列翻转
            {
                a.data^=1<<(j+4);
                j+=4;
            }
            j=i;
            while(j>=4)
            {
                a.data^=1<<(j-4);
                j-=4;
            }
            j=i;
            while(j%4)//此位点行翻转
            {
                a.data^=1<<(j-1);
                j--;
            }
            j=i;
            while((j+1)%4)
            {
                a.data^=1<<(j+1);
                j++;
            }//上面写的异或的代码很长而且提交TLE*/
            a.data=Q.front().data^ID[i];//异或
            if(!vis[a.data])
            {
                a.num=++m;
                a.step=Q.front().step+1;
                p[m].pre=Q.front().num;//存点,以便路径回溯
                p[m].x=i;
                Q.push(a);
                vis[a.data]=1;
            }
        }
        Q.pop();
    }
}

int main()
{
    char s[maxn];
    for(int i=0; i<maxn; i++)
    {
        scanf("%s",s);
        for(int j=0; j<maxn; j++)
        {
            id*=2;
            if(s[j]=='+')
            {
                id+=1;
            }
        }
    }
    BFS();
    return 0;
}

 2.在POJ的讨论中看到大牛的一种高效方法之后写的代码

~大牛解题链接~    http://poj.org/showmessage?message_id=156561

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#define maxn 4

using namespace std;

int flag[maxn][maxn];
struct node
{
    int x,y;
}N;

int main()
{
    char s[maxn][maxn];
    memset(flag,true,sizeof(flag));
    for(int i=0; i<maxn; i++)
    scanf("%s",s[i]);
    for(int i=0; i<maxn; i++)
    for(int j=0; j<maxn; j++)
    if(s[i][j]=='+')
    {
        flag[i][j]=!flag[i][j];
        for(int k=0; k<maxn; k++)
        {
            flag[k][j]=!flag[k][j];
            flag[i][k]=!flag[i][k];
        }
    }
    int num=0;
    queue<struct node>Q;
    for(int i=0; i<maxn; i++)
    for(int j=0; j<maxn; j++)
    if(!flag[i][j])
    {
        N.x=i;
        N.y=j;
        Q.push(N);
        num++;
    }
    printf("%d
",num);
    while(!Q.empty())
    {
        printf("%d %d
",Q.front().x+1,Q.front().y+1);
        Q.pop();
    }

    return 0;
}
原文地址:https://www.cnblogs.com/guoyongzhi/p/3236398.html