poj 2965 The Pilots Brothers' refrigerator bfs+狀態壓縮+路徑回溯

此題易超時,因爲16個開關,每個開關有兩種狀態,可以將’-‘看成0,’+’看成1,從第一排第一個到第四排最後一個,每一種狀態都可以用一個數字來代替,所以一共是(1<<16)-1種狀態,即65535種,bfs還是可以的。在廣搜過程中,因爲每一個開關扳動的過程其對應的一行及一列都會發生變化,可以將其狀態對應的值分別和這些狀態對應的數字進行^處理,爲了防止TLE,可以提前打個表,這樣異或一下就可以了,不用異或7次。
路徑回溯可以再開一個結構體,對應每一次搜索都給定一個次序,在結構體裏面存兩個值,一個對應改變的行列,一個對應狀態改變之前的那個次序,這樣在廣搜搜到最終狀態的時候就可以了一步一步回溯到最終的結果。
題目:
The Pilots Brothers’ refrigerator
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 23926 Accepted: 9221 Special Judge
Description

The game “The Pilots Brothers: following the stripy elephant” has a quest where a player needs to open a refrigerator.

There are 16 handles on the refrigerator door. Every handle can be in one of two states: open or closed. The refrigerator is open only when all handles are open. The handles are represented as a matrix 4х4. You can change the state of a handle in any location [i, j] (1 ≤ i, j ≤ 4). However, this also changes states of all handles in row i and all handles in column j.

The task is to determine the minimum number of handle switching necessary to open the refrigerator.

Input

The input contains four lines. Each of the four lines contains four characters describing the initial state of appropriate handles. A symbol “+” means that the handle is in closed state, whereas the symbol “−” means “open”. At least one of the handles is initially closed.

Output

The first line of the input contains N – the minimum number of switching. The rest N lines describe switching sequence. Each of the lines contains a row number and a column number of the matrix separated by one or more spaces. If there are several solutions, you may give any one of them.

Sample Input

-+–


-+–
Sample Output

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

代碼:

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
char a[8][8];
bool c[100000];
int  multi[16]= {4383, 8751, 17487,34959,
                 4593, 8946,17652, 35064,
                 7953,12066,20292,36744,
                 61713,61986, 62532,63624
                },k=0;             //手動打表
struct stu
{
    int x,step,num;
} s;
struct st
{
    int x,pre;
} d[100001];
void present(int num)
{
    if(num)
    {
        present(d[num].pre);
        printf("%d %d\n",(d[num].x)/4+1,(d[num].x)%4+1);
    }
}
bool mach(int i,stu t)
{
    s.x=t.x;
    s.x=s.x^multi[i];
    if(!c[s.x])
    {
        s.num=++k;
        d[k].x=i;
        d[k].pre=t.num;
        s.step=t.step+1;
        c[s.x]=1;
        return 1;
    }
    return 0;
}
void bfs()
{
    queue<stu>q;
    q.push(s);
    stu t;
    int i,j;
    while(!q.empty())
    {
        t=q.front();
        q.pop();
        if(!t.x)
        {
            printf("%d\n",t.step);
            present(t.num);
        }//路徑回溯
        else
        {
            for(i=0; i<16; i++)
            {
                if(mach(i,t))
                    q.push(s);
            }
        }
    }
}
int main()
{
    int i,j;
    while(scanf("%s",a[1]+1)!=EOF)
    {
        memset(c,0,sizeof(c));
        s.x=0,s.step=0,k=0,s.num=0;
        for(i=2; i<=4; i++)
            scanf("%s",a[i]+1);
        for(i=1; i<=4; i++)
            for(j=1; j<=4; j++)
                if(a[i][j]=='+')
                    s.x^=(1<<(j-1+(i-1)*4));   //狀態壓縮
        if(s.x)
            c[s.x]=1;
        bfs();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章