我的解法不是很难懂,就是暴力得到所有翻棋子的位置,然后再比较最小的翻棋子个数
时间和空间我都没有优化,位运算也只用了一个异或 :P
本题有三点大前提:
1. 所有的棋子只有“翻”和“不翻”两种状态
2.翻奇数次次棋子相当于“翻”,翻偶数次棋子相当于“不翻”
3.翻棋子的顺序不影响结果,所以本题求组合,而不是排列
首先我定义了三个全局变量:
int chess[4][4]; 定义棋盘的棋子状态,黑色为1,白色为0
bool isFilp[4][4];定义当前棋子是否反转
int time = -1;最小的翻转棋子个数,-1为没找到
bool checkstate()
{
int state = chess[0][0];
for (int i = 0;i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (chess[i][j] != state)
return false;
}
}
return true;
}
本函数检查是否棋子都为统一的颜色
int getTimes()
{
int curtime = 0;
for (int i = 0;i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (isFilp[i][j])
curtime++;
}
}
return curtime;
}
本函数计算翻转棋子的个数
void flip( int i, int j)
{
chess[i][j]^=1;
if (i - 1 >= 0)
chess[i-1][j] ^= 1;
if (i + 1 < 4)
chess[i+1][j] ^= 1;
if (j - 1 >= 0)
chess[i][j-1] ^= 1;
if (j + 1 < 4)
chess[i][j+1] ^= 1;
}
本函数模拟翻转棋子
void search(int index)
{
if (index == 16)
{
if (checkstate())
{
if (time == -1)
time = getTimes();
else
{
int tempTime = getTimes();
time = tempTime < time ? tempTime:time;
}
return;
}else
return;
}
isFilp[index / 4][index % 4] = true;
flip(index / 4, index % 4);
search(index + 1);
isFilp[index / 4][index % 4] = false;
flip(index / 4, index % 4);
search(index + 1);
}
void search()
{
isFilp[0][0] = true;
flip(0,0);
search(1);
isFilp[0][0] = false;
flip(0,0);
search(1);
}
这两个函数递归得到所有的翻转棋子位置组合,然后测试这样的翻转组合是否能让棋子颜色统一
index表明递归的层数,当index为16时,0-15这16个位置的棋子都处理了,得到的是一种组合
程序如下:
#include<iostream>
using namespace std;
int chess[4][4];
bool isFilp[4][4];
int time = -1;
bool checkstate()
{
int state = chess[0][0];
for (int i = 0;i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (chess[i][j] != state)
return false;
}
}
return true;
}
int getTimes()
{
int curtime = 0;
for (int i = 0;i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (isFilp[i][j])
curtime++;
}
}
return curtime;
}
void flip( int i, int j)
{
chess[i][j]^=1;
if (i - 1 >= 0)
chess[i-1][j] ^= 1;
if (i + 1 < 4)
chess[i+1][j] ^= 1;
if (j - 1 >= 0)
chess[i][j-1] ^= 1;
if (j + 1 < 4)
chess[i][j+1] ^= 1;
}
void search(int index)
{
if (index == 16)
{
if (checkstate())
{
if (time == -1)
time = getTimes();
else
{
int tempTime = getTimes();
time = tempTime < time ? tempTime:time;
}
return;
}else
return;
}
isFilp[index / 4][index % 4] = true;
flip(index / 4, index % 4);
search(index + 1);
isFilp[index / 4][index % 4] = false;
flip(index / 4, index % 4);
search(index + 1);
}
void search()
{
isFilp[0][0] = true;
flip(0,0);
search(1);
isFilp[0][0] = false;
flip(0,0);
search(1);
}
int main ()
{
char temp;
for (int i = 0;i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
cin >> temp;
if (temp == 'b')
chess[i][j] = 1;
else
chess[i][j] = 0;
}
}
if (checkstate())
{
cout << "0" << endl;
return 0;
}
search();
if (time == -1)
{
cout << "Impossible" << endl;
}else
{
cout << time << endl;
}
return 0;
}