Poj2965 冰箱的开关

#include<iostream>
using namespace std;

int flag;
int step;
int loction[6][6];
int r[16] = { 0 };
int c[16] = { 0 };


void turn(int i, int j) //转换
{
    for (int q = 0; q < 4; q++)
    {
        loction[i][q] = !(loction[i][q]);
    }
    for (int p = 0; p < 4; p++)
    {
        if (p != i)
        {
            loction[p][j] = !(loction[p][j]);
        }
    }
    
}



int range()//判定表格是否全部一样
{
    int i, j;
    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 4; j++)
        {
            if (loction[i][j] != 1)
            {
                return 0;
            }
        }
    }
    return 1;
}


int DFS(int i, int j, int dp)//深搜(dp<=step)
{
    //对第dp次的转换作判断
    if (dp == step)
    {
        flag = range();
        return 0;
    }
    if (flag || i == 4)
    {
        return 1;
    }

    //没有以上两种可以直接退出函数的情况,
    //说明此时的dp<step,就进行第dp+1次的转换
    turn(i, j); 
//对当前转换的主位置(i,j)作记录 r[dp] = i+1; c[dp] = j + 1; //对第dp+1次的转换进行判断 if (j < 3) { //判断的是第dp+1次时转换的turn(i,j), //如果判断成功,直接退出函数。 //如果判断失败,要继续进行下一列(即j+1)的递归转换和判断 //j+1不影响对第dp+1次转换的turn(i,j)的判断 //因为在DFS()函数里,判断turn(i,j)的步骤总在turn(i,j+1)前面 DFS(i, j+1, dp + 1); } else { //判断的是第dp+1次时转换的turn(i,j), //如果判断成功,直接退出函数。 //如果判断失败,要继续进行下一行(即i+1)的递归转换和判断 //i+1不影响对第dp+1次转换的turn(i,j)的判断 //因为在DFS()函数里,判断turn(i,j)的步骤总在turn(i+1,j)前面 DFS(i + 1, 0, dp+1); } turn(i, j); //不符合条件,重新转换回来 //第dp次时,表格恢复初始状态 if (j < 3) { DFS(i, j + 1, dp ); //进行对下一列进行第dp次的转换() } else { DFS(i + 1, 0, dp); //进行对下一行进行第dp次的转换 } return 0; } int main() { char tmp; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { scanf("%c", &tmp); if (tmp == '-') { loction[i][j] = 1; } else { loction[i][j] = 0; } } getchar(); //不要遗忘 } for (step = 0; step <= 16; step++) { flag = 0; DFS(0, 0, 0); if (flag) break; } if (flag) { cout << step << endl; for (int i = 0; i < step; i++) { cout << r[i] << " " << c[i] << endl; } } return 0; }

 

posted @ 2016-11-24 13:23  Strugglinggirl  阅读(216)  评论(0编辑  收藏  举报