关闭

翻转游戏题解

标签: C++bfs编程
333人阅读 评论(0) 收藏 举报
分类:

题目描述

翻转游戏是这样玩的:

有一张4*4的棋盘,在16个位置上每个位置放着一个棋子,棋子一面是黑色,另一面是白色,棋子或者白色面朝上,或者黑色面朝上。游戏的走法如下:每一步先选择一个位置,然后把该位置和上,下,左,右(不越界)相邻位置上的棋子翻转(白->黑,黑->白)。我们用w表示棋子白色面朝上,b表示黑色面朝上。

例如:考虑如下棋盘状态:

bwbw

wwww

bbwb

bwwb

当我们选择第三行,第一列的位置翻转时,棋盘变化为:

bwbw

bwww

wwwb

wwwb

游戏的目的是用最少的步数把全部棋子变为白色向上或黑色向上。

时限:1s

输入格式

4行由b和w组成的字符串描述的一个棋盘的初始状态。

输出格式

一个测试数据输出一行,为所需要的最少的翻转次数,如果无法翻转成目标状态,则输出’impossible’(小写,没有引号)。

样例输入(1

bwbw

wwww

bbwb

bwwb

样例输出(1

Impossible

样例输入(2

bwwb

bbwb

bwwb

bwww

样例输出(2

4

 

解题思路:

BFS搜索加哈希判重。将w设置为0,b设置为1。把16个位置的数据当做二进制数,将二进制转换为十进制数。

2^16=65536,用于判重的哈希数组并不会很大,可以实现。

类似的题目还有八数码问题,只不过八数码的哈希表为康托展开。八数码:https://www.rqnoj.cn/problem/70

AC代码:

#include<iostream>

#include<queue>

#include<cstring>

usingnamespace std;

 

typedefstruct table

{

   int pic[6][6];

}table;

 

tablestart;   //初始状态

 

intP[16]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};

boolvis[65536];  //状态数组

intdist[65536];

queue<table>Q;

 

//黑0 白1

charNegate(int ch)

{

   if(ch)

      return 0;

   return 1;

}

 

voidturn(int x,int y,table &T)

{

   T.pic[x][y]=Negate(T.pic[x][y]); //自身

   T.pic[x][y-1]=Negate(T.pic[x][y-1]);   //左侧

   T.pic[x][y+1]=Negate(T.pic[x][y+1]);   //右侧

   T.pic[x-1][y]=Negate(T.pic[x-1][y]);   //上侧

   T.pic[x+1][y]=Negate(T.pic[x+1][y]);   //下侧

}

 

intget_dec(table T)    //位压缩 

{

   int dec=0;

   int s=0;

   for(int i=4;i>0;--i)

   for(int j=4;j>0;--j)

   {

      dec+=T.pic[i][j]*P[s];

      s++;

   } 

   return dec;

}

 

intBFS()

{

   Q.push(start); //初始状态入队

   int st=get_dec(start);    //获取索引

   vis[st]=true;

   int front=1,rear=2;

   table Now;

   while(front<rear)

   {

      Now=Q.front();   //头结点出队

      Q.pop();

      int index=get_dec(Now);   //获取索引

      if(index==0||index==65535)   //找到终点

        return front;

      for(int i=0;i<16;++i)

      {

        int x=i/4+1;   //横坐标 

        int y=i%4+1;   //纵坐标

        table Next=Now;

        turn(x,y,Next);   //变换求下一步

        int ni=get_dec(Next);

        if(!vis[ni])

        {

           vis[ni]=true;

           Q.push(Next);

           dist[rear]=dist[front]+1;

           rear++;

        }

      }

      front++;

   }

   return -1;

}

intmain()

{

   for(int i=0;i<6;++i)

   for(int j=0;j<6;++j)

      start.pic[i][j]=0;

   memset(vis,0,sizeof(vis));

   for(int i=1;i<=4;++i)

   for(int j=1;j<=4;++j)

   {

      char ch;

      cin>>ch;

      if(ch=='w')

        start.pic[i][j]=0;

      else

        start.pic[i][j]=1;    

   }

   int s=BFS();

   if(s!=-1)

      cout<<dist[s]<<endl;

   else

      cout<<"impossible"<<endl;

   return 0;

}

 

0
0
查看评论

一款“翻转”小游戏的解法

类似2048这样的智力小游戏,玩玩
  • Honkhat
  • Honkhat
  • 2014-09-10 16:33
  • 2050

NOIP模拟题题解

这套题是一位学长出的=-=关于我们热爱的小机房(但由于强行用梗,部分题意不清),很不幸的是我那天刚好秀逗了,成为了唯一一个爆零的 1.【真●翻转游戏】 flip.cpp 【题目描述】 “4*4的翻转游戏太简单了”,kkke心想,“如果变成n*n的会怎么样?” 于是kkke找来了一个更大的棋盘(其实...
  • captain_Ben
  • captain_Ben
  • 2015-11-01 10:45
  • 261

[编程题] 01翻转

牛牛正在挑战一款名为01翻转的游戏。游戏初始有A个0,B个1,牛牛的目标就是把所有的值都变为1,每次操作牛牛可以任意选择恰好K个数字,并将这K个数字的值进行翻转(0变为1,1变为0)。牛牛如果使用最少的操作次数完成这个游戏就可以获得奖品,牛牛想知道最少的操作次数是多少? 例如:A = 4 B = ...
  • qq_32199531
  • qq_32199531
  • 2017-04-07 16:12
  • 470

洛谷 P1080 国王游戏

贪心+高精度
  • Rlt1296
  • Rlt1296
  • 2016-10-11 23:39
  • 279

Cocos2D游戏之旅(三):卡牌翻转效果的实现(上)

晓石头的博客 邮箱:178673693@qq.com 第一步:将正面的宽度慢慢缩小至0;产生卡牌翻转到中间的效果 第二步:将一开始就把宽度缩小至0的背面放大到正常,产生卡牌盖住的效果
  • QIULANZHU
  • QIULANZHU
  • 2015-08-02 23:57
  • 2017

关于十字翻转棋的解法研究

首先说什么是十字翻转棋,十字翻转棋又叫开窗游戏,游戏规则如下: 在n*n的方格中随机分布着一些关着的窗子,当你打开或关闭一个窗子时,它的上下左右四个方向的窗子开关状态也会翻转。目标是将这些关着的窗子都打开,游戏结束。  这里有一个我自己编写的html5开窗游戏,大家可以先去玩一下: ...
  • gagaprince
  • gagaprince
  • 2016-01-17 15:46
  • 2018

游戏面试题库(1)

最近又要开始找工作了,虽然已经做了1年多的游戏开发,但是面试关还是十分担心,因为毕竟是有时间限制和心理压力的,所以找了点面试题做了做,不足的地方希望大家指点。一、实模式与保护模式。为什么要设计这两种模式?好处在什么地方?分别写出各自寻址的过程。 答案:机器状态字MSW(也就是CR0寄存器的低16位)...
  • yinqing_yx
  • yinqing_yx
  • 2008-02-23 13:30
  • 791

扫雷(BZOJ1088) 题解

【问题描述】     相信大家都玩过扫雷的游戏。那是在一个n*m的矩阵里面有一些雷,要你根据一些信息找出雷来。万圣节到了,“余”人国流行起了一种简单的扫雷游戏,这个游戏规则和扫雷一样,如果某个格子没有雷,那么它里面的数字表示和它8连通的格子里面雷的数目。现在棋盘是n×...
  • PbTfcLx
  • PbTfcLx
  • 2016-01-10 18:42
  • 526

5X5点灯游戏

 初学所写的数字游戏,无奈智商太低,一直都未打赢。#include #include void print(int l[5][5]) { int i; for(i=0;i<5;i++) ...
  • beimingmuyu
  • beimingmuyu
  • 2015-05-22 10:28
  • 1272

51Nod-1337-翻转游戏

ACM模版描述题解首先逐关进行两次遍历,遍历第一遍,查找到开关操作是否需要,再遍历一遍,检索?,如果遇见?则向下一组查找对应位置,直到查找到最后一关卡,或者不是?的关卡,这时,根据此关卡是否进行相关开关操作来改变后边关卡的对应位置的状态,具体有三大种五小种状态,逐一分析,逐一修正即可。代码#incl...
  • f_zyj
  • f_zyj
  • 2016-09-09 16:42
  • 306
    个人资料
    • 访问:20596次
    • 积分:531
    • 等级:
    • 排名:千里之外
    • 原创:33篇
    • 转载:0篇
    • 译文:0篇
    • 评论:20条
    文章分类