The Pilots Brothers' refrigerator POJ - 2965

问题:

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

大意:

4*4的方格,你可以任选一个位置把‘ - ’变为‘ + ’,或把‘ + ’变为‘ - ’然后他所在的行和列上所有位置都要改变。问你最少多少次,可以把所有的都变成‘ - ’。然后把变换次数和位置位置输出出来。

思路:

深搜去模拟这个过程,用标记数组去标记变换次数。遍历数组,当走到某一位置时有变换或者不变换两种情况。当变换次数为偶数说明,变换后的符号和原来一样,为奇数则相反。

代码:

#define N 6
#include<queue>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
char k[N][N];
int book[N][N];
int c[N][N],sp[N][N];
int bl,ma;
void dfs(int xy,int bnum,int step)//xy:当前位置,bnum:减号的个数,step:变换了几次
{
    if(bnum==16)//当都变成 - 号
    {
        if(step<ma)//保留最少次数和变换位置
        {
            ma=step;
            for(int i=0; i<6; i++)
                for(int j=0; j<6; j++)
                    c[i][j]=sp[i][j];
        }
        return ;
    }
    if(xy>=16)return;
    dfs(xy+1,bnum,step);  //走到这个位置不变换符号
    //下面为变换符号,我们去统计 - 号数量
    int x=xy/4;
    int y=xy%4;//在二维数组中的位置
    int bum=bnum;
    //遍历行和列
    for(int i=0; i<4; i++)
    {
        book[i][y]++;//变换次数+1
        if(k[i][y]=='-'&&(book[i][y]%2)==0)bum++;//如果’-‘转变了偶数次,还是‘-’‘-’数量就+1
        else if(k[i][y]=='+'&&(book[i][y]%2)==1)bum++;//’+‘变换了奇数次,也是‘-’,+1;
        else bum--; //否则就会变成 ’+‘, ’-‘号-1
    }
    for(int i=0; i<4; i++)//这个和上面的一样
    {
        if(i==y)continue;
        book[x][i]++;
        if(k[x][i]=='-'&&(book[x][i]%2)==0)bum++;
        else if(k[x][i]=='+'&&(book[x][i]%2)==1)bum++;
        else bum--;
    }
    sp[x][y]=1;//记录变换位置
    dfs(xy+1,bum,step+1);
    //还原
    for(int i=0; i<4; i++)book[i][y]--;
    for(int i=0; i<4; i++)
    {
        if(i==y)continue;;
        book[x][i]--;
    }
    sp[x][y]=0;
}
int main()
{
    while(~scanf("%s",k[0]))
    {
        for(int i=1; i<4; i++)
            scanf("%s",k[i]);
        bl=0;
        ma=0x3f3f3f3f;
        for(int i=0; i<4; i++)
            for(int j=0; j<4; j++)
                if(k[i][j]=='-')
                    bl++;           //计算 - 的个数
        memset(book,0,sizeof(book));//保留变换次数
        memset(sp,0,sizeof(sp));
        dfs(0,bl,0);
        printf("%d\n",ma);
        for(int i=0; i<4; i++)
            for(int j=0; j<4; j++)
                if(c[i][j])
                    printf("%d %d\n",i+1,j+1);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lxxdong/article/details/81225223