poj1753 flip game

中文翻译在这里,http://blog.sina.com.cn/s/blog_61eccf0e0100g1gs.html
这道题目是一个翻牌问题,对于同一格,翻1次,格子会变得和原来相反,再翻一次,那么格子就会变回原来的内容,在翻一次,格子又会变得相反。
因此,我们可以知道,翻牌翻奇数次的效果跟翻一次是一样的,翻偶数次是不会改变棋盘内容的。
因此对于一个4*4的棋盘来说,最多只能翻16次。
那么我们就可以把4*4的棋盘内容全都一样作为最终判断的结果,以输入棋盘的内容作为起点,然后枚举翻牌n次的每一种可能。看看哪一次能够得出最终结果。
#include <iostream>
using namespace std;
int rnext[5][2] = { 0,0,0,-1,0,1,-1,0,1,0 };
bool flag;
bool map[6][6] = {false};
int step;
bool judge()
{
 int i, j;
 for (i = 1; i <= 4; i++)
  for (j = 1; j <= 4; j++)
   if (map[i][j] != map[1][1])
    return false;
 return true;
}
void flip(int row, int col)
{
 int i;
 for (i = 0; i < 5; i++)
 {
  map[row + rnext[i][0]][col + rnext[i][1]] = !map[row + rnext[i][0]][col + rnext[i][1]];
 }
 return;
}
void dfs(int row, int col, int deep)
{
 int i, j;
 if (deep == step)
 {
  flag = judge();
  return;
 }
 if (flag || row == 5)
  return;
 flip(row, col);
 if (col < 4)
  dfs(row, col + 1, deep + 1);
 else
  dfs(row + 1, 1, deep + 1);
 flip(row, col);
 if (col < 4)
  dfs(row, col + 1, deep);
 else
  dfs(row + 1, 1, deep);
 return;
}
int main()
{
 char temp;
 int i, j;
 for (i = 1; i <= 4; i++)
  for (j = 1; j <= 4; j++)
  {
   cin >> temp;
   if (temp == 'b')
    map[i][j] = true;
  }
 for (step = 0; step <= 16; step++)
 {
  dfs(1,1,0);
  if (flag)
   break;
 }
 if (flag)
  cout << step << endl;
 else
  cout << "Impossible" << endl;
 return 0;
}

你可能感兴趣的:(枚举,递归)