就是对一个4X4的棋盘进行翻转,每一次翻转都将让同一行和列一起翻转,直到所有符号都变为‘-’时成功。
通过枚举加上深度优先搜索的方法进行解决,枚举通过行号和列号顺序进行,每个位置都有翻转和不翻转两种选择(通过一个位置两次翻转来回溯)
//poj 2965
//244K 844MS
#include <iostream>
using namespace std;
bool OpenClose[6][6] = {false};
int TotalDeep = 0;
bool flag = false;
int theLoc[17][2] = {0};
//struct turnLoc
//{
// int Loc[17][2];
// int nowLoc;
//};
//
//turnLoc myturn;
//
//void pushTurn(int row, int col) //本来设计的用于压入操作步骤的函数
//{
// int now = myturn.nowLoc;
// myturn.Loc[now][0] = row;
// myturn.Loc[now][1] = col;
// myturn.nowLoc++;
//}
//
//void popTurn()
//{
// myturn.nowLoc--;
//}
bool WhetherOpen()
{
for (int i=1; i<5; i++)
for (int j=1; j<5; j++)
{
if (OpenClose[i][j] != true) //有任何一个锁没有打开,都是false
{
return false;
}
}
return true;
}
void TurnIt(int row, int col)
{
for (int i=1; i<5;i++)
{
OpenClose[row][i] = !OpenClose[row][i];
OpenClose[i][col] = !OpenClose[i][col];
}
OpenClose[row][col] = !OpenClose[row][col]; //翻转了两次,翻一次回来
}
void dfs(int row, int col, int nowDeep)
{
if (flag == true)
{
return;
}
if (nowDeep == TotalDeep || row == 5)
{
flag = WhetherOpen();
return;
}
//当前位置没有翻转过,翻转他
TurnIt(row, col);
//pushTurn(row, col);
theLoc[nowDeep][0] = row;
theLoc[nowDeep][1] = col;
if (col < 4)
{
dfs(row, col+1, nowDeep+1);
}
else
dfs(row+1, 1, nowDeep+1);
TurnIt(row,col);
//popTurn();
//跳过当前位置,直接翻转下一个位置
if (col < 4)
{
dfs(row, col+1, nowDeep);
}
else
dfs(row+1, 1, nowDeep);
}
int main()
{
//memset(&myturn, 0, sizeof(turnLoc));
char forInput ;
for (int i=1; i<5;i++)
for (int j=1; j<5; j++)
{
cin>>forInput;
if (forInput == '-')
{
OpenClose[i][j] = true;
}
}
for (TotalDeep= 0; TotalDeep<=16; TotalDeep++)
{
dfs(1,1,0);
if (flag == true)
{
cout<<TotalDeep<<endl;
for (int tu = 0; tu<TotalDeep; tu++)
{
//cout<<myturn.Loc[tu][0]<<" "<<myturn.Loc[tu][1]<<endl;
cout<<theLoc[tu][0]<<" "<<theLoc[tu][1]<<endl;
}
break;
}
}
//system("pause");
return 0;
}