POJ 2965-The Pilots Brothers' refrigerator(枚举&&DFS&&输出过程)

The Pilots Brothers' refrigerator

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 23018   Accepted: 8862   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

Source

Northeastern Europe 2004, Western Subregion

题目意思:
有一个4*4方阵保存门上16个开关的状态,+表示关闭,-表示开放,只有当所有状态都是-开放的时候门才能打开。
每次改变一个开关状态的时候,它的当前行列各开关的状态都发生改变;
求最少多少步能打开门,并输出改变了哪些位置的开关。

解题思路:
就是比
POJ 1753-Flip Game 多了一个输出路径的过程。
可以先每次都保存当前搜索状态下的路径,如果取得Min再存入答案路径,最后直接输出答案路径。


/*
* Copyright (c) 2016, 烟台大学计算机与控制工程学院
* All rights reserved.
* 文件名称:filp game2.cpp
* 作    者:单昕昕
* 完成日期:2016年4月26日
* 版 本 号:v1.0
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int p[4][4];//存储初始状态
int path[16][2];//存储当前状态下的路径
int ans[16][2];//存储取得min时的路径
int Min=0x7fffffff;
int check()//检查是否都是-开放的
{
    int i,j;
    for(i=0; i<4; ++i)
        for(j=0; j<4; ++j)
            if(p[i][j]==1)
                return -1;
    return 1;
}
void change(int i,int j)//改变自己和上下左右的颜色
{

    int k;
    int flag=p[i][j];//记录自己的位置的状态
    for(k=0; k<4; ++k)//改变当前行
        p[k][j]=!p[k][j];
    for(k=0; k<4; ++k)//改变当前列
        p[i][k]=!p[i][k];
    if(flag==1) p[i][j]=0;//改变自己的位置的状态
    else p[i][j]=1;
}
void dfs(int d,int step)//枚举深搜
{
    int x,y;
    if(d==16)
    {
        if(check()==1)
            if(step<Min)
            {
                Min=step;
                for(int k=0; k<step; ++k)
                {//记录路径
                    ans[k][0]=path[k][0];
                    ans[k][1]=path[k][1];
                }
            }
        return;
    }
    else
    {
        x=d/4;//行
        y=d%4;//列
        dfs(d+1,step);
        change(x,y);//不行就翻回来
        path[step][0]=x;//记录当前路径
        path[step][1]=y;
        dfs(d+1,step+1);
        change(x,y);
    }
}
int main()
{
    int i,j;
    char t;
    memset(p,0,sizeof(p));
    for(i=0; i<4; ++i)
        for(j=0; j<4; ++j)
        {
            cin>>t;
            if(t=='+')
                p[i][j]=1;//1表示+关闭,0表示-开放
        }
    dfs(0,0);
    if(Min==0x7fffffff)//0x7fffffff是int的最大值
        cout<<"Impossible"<<endl;
    else
    {
        cout<<Min<<endl;
        for(int k=0; k<Min; ++k)//输出路径
            cout<<++ans[k][0]<<" "<<++ans[k][1]<<endl;
    }
    return 0;
}


你可能感兴趣的:(枚举,poj,poj,DFS,the,brothers,2965,Pilots)