POJ1753 Flip Games

it2022-05-17  78

开始的时候自己读完题目,知道它的目的,但是如何做,脑子里还没有一个清晰的思路。因为某种原因,我直接网上搜了别人的思路,知道了题目的思路,下午边上课边写程序,发现原来是这么简单的题目。下面是给我启发的那篇文章:

转载自:http://blog.csdn.net/zengniao/article/details/6644793  

题目:http://poj.org/problem?id=1753

   Flip Game题目大意是在一个4*4的棋盘上翻转棋子,翻转了一个棋子以后,他的上下左右四个方向的棋子都得跟着变色,最后使得棋盘上所有的棋子都是白色,或者都是黑色。统计要翻转的棋子的个数。分析:

      1. 棋子只有黑白两色,因此如果翻转同一个棋子不能超过一次。因为翻转两次就等于没有翻。

       2. 相同棋子之间的翻转顺序是不会影响最终翻转的结果的。

      那么上面有16个棋子,也就是16个棋子处于两种状态,需要翻转,不需要翻转,总共有2^16次方种方案。因此采用枚举的方法就可以了。

      数据结构:我们用位表示一个格子,那么4位组成一个16进制数,表示一行。用相应的位^1表示翻转,可以提前算出16种翻转的状态。如下:

const int state[16] = {0xC800, 0xE400, 0x7200, 0x3100,                          0x8C80, 0x4E40, 0x2720, 0x1310,                         0x08C8, 0X04E4, 0X0272, 0X0131,                         0X008C, 0X004E, 0X0027, 0X0013};  //搜索采用回溯策略 #include <stdio.h>     #define ONLINE     void online()  {  #ifdef ONLINE   #else       freopen("1753.in""r", stdin);      freopen("1753.out","w", stdout);  #endif   }    int map = 0;  const int END1 = 0x0000;  const int END2 = 0xFFFF;  const int state[16] = {0xC800, 0xE400, 0x7200, 0x3100,                                   0x8C80, 0x4E40, 0x2720, 0x1310,                                  0x08C8, 0X04E4, 0X0272, 0X0131,                                  0X008C, 0X004E, 0X0027, 0X0013};  int result = 17;    void read()  {      char c;      for (int i=0; i < 16; i ++)      {          c = getchar();          //scanf("%c", &c);           if (c == 'b')          {              map = map << 1;              map =(map^1);           }          else if(c=='w')          {              map = map<<1;          }          else              i --;      }  }    void search( int idx, int step)  {      if (step >= result)      {          return;      }        if (idx >= 16)      {          if (map == END2 || map == END1)          {              if (step < result)              {                  result = step;              }//end if step           }//end if map           return;      }        search(idx+1, step);      map = map ^ state[idx];      search(idx+1, step+1);      map = map^state[idx];      return;  }    void print()  {      if (result >= 17)      {          printf("Impossible");      }      else          printf("%d",result);  }    int main()  {      online();      read();      search(0, 0);      print();      return 0;  }  

通过此题呢,我学到了用位存储信息,以前苏哥给我讲用位做八皇后,当时觉得很巧妙,但是自己没有吸收。

今天做了这道题,进一步发现了位存储矩阵信息的优点,不仅节省空间,还节省时间。妙~

一时兴起,还根据这个小算法做了一个小程序【360vsQQ】,很久没碰MFC了、这次的代码除了算法部分、其他的基本都是copy的以前写的【残缺棋盘】程序:

//主界面

//解

//说明书

转载于:https://www.cnblogs.com/CheeseZH/archive/2012/04/11/2443123.html

相关资源:数据结构—成绩单生成器

最新回复(0)