POJ1753 Flip Game DFS+枚举

来源:互联网 发布:软件实施顾问发展前景 编辑:程序博客网 时间:2024/06/07 20:24

题目大意:有一个4×4的棋盘,棋盘上每一点都有黑白两面,每次可以翻转任意一点,在翻转某一点时,该点上下左右的4个临近点同时也会被翻转,现在问你要使棋盘上所有点的颜色统一所需要的最小翻转次数。

分析:其实这道题是典型的高斯消元,不过我是用DFS来做的。

首先我们知道,对于棋盘上任意一点,翻转偶数次是没有意义的,翻转奇数次和翻转一次是一样的,这就意味着,最大的翻转次数也不会超过4×4=16次,这样我们就可以枚举每一次翻转,看是否满足题意,第一个满足题意的翻转次数即为最终结果。

实现代码如下:

#include <cstdio>#include <iostream>using namespace std;int map[10][10]={0};//考虑到要不断翻转,我们用0和1代表棋盘黑白两种颜色,这样翻转就可以用“非”运算符来代替了int dir[5][2]={{-1,0},{1,0},{0,-1},{0,1},{0,0}};int sum;bool flag;void flip(int x,int y)//翻转(x,y)及其相邻点{    for(int i=0;i<=4;i++)      map[x+dir[i][0]][y+dir[i][1]]=!map[x+dir[i][0]][y+dir[i][1]];    return ;}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 dfs(int x,int y,int ans)//ans纪录翻转次数{    if(ans==sum)    {        flag=judge();        return ;    }    if(flag||x==5) return ;    flip(x,y);    if(y<4)  dfs(x,y+1,ans+1);    else dfs(x+1,1,ans+1);    flip(x,y);    if(y<4)  dfs(x,y+1,ans);    else dfs(x+1,1,ans);    return ;}int main(){    int i,j;    char tmp;    for(i=1;i<=4;i++)      for(j=1;j<=4;j++)      {          cin>>tmp;          if(tmp=='w')  map[i][j]=1;//白色记为1,黑色记为0      }    for(sum=0;sum<=16;sum++)//枚举16次翻转    {        dfs(1,1,0);        if(flag) break;    }    if(flag)  printf("%d\n",sum);    else puts("Impossible");    return 0;}


0 0
原创粉丝点击