题目描述

Mayan puzzle 是最近流行起来的一个游戏。游戏界面是一个7 行 5×5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上。游戏通关是指在规定的步数内消除所有的方块,消除方块的规则如下:

  1. 每步移动可以且仅可以沿横向(即向左或向右)拖动某一方块一格:当拖动这一方块时,如果拖动后到达的位置(以下称目标位置)也有方块,那么这两个方块将交换位置(参见输入输出样例说明中的图 6 到图 7);如果目标位置上没有方块,那么被拖动的方块将从原来的竖列中抽出,并从目标位置上掉落(直到不悬空,参见下面图 1 和图 2);
  2. 任一时刻,如果在一横行或者竖列上有连续三个或者三个以上相同颜色的方块,则它们将立即被消除(参见图1 到图3)

注意:

a) 如果同时有多组方块满足消除条件,几组方块会同时被消除(例如下面图 4,三个颜色为 1 的方块和三个颜色为 2 的方块会同时被消除,最后剩下一个颜色为 2 的方块)。

b) 当出现行和列都满足消除条件且行列共享某个方块时,行和列上满足消除条件的所有方块会被同时消除(例如下面图5 所示的情形,5 个方块会同时被消除)。

方块消除之后,消除位置之上的方块将掉落,掉落后可能会引起新的方块消除。注意:掉落的过程中将不会有方块的消除。

上面图 1 到图 3 给出了在棋盘上移动一块方块之后棋盘的变化。棋盘的左下角方块的坐标为 (0,0)(0,0),将位于 (3,3)(3,3) 的方块向左移动之后,游戏界面从图 1 变成图 2 所示的状态,此时在一竖列上有连续三块颜色为 4 的方块,满足消除条件,消除连续 3 块颜色为 4 的方块后,上方的颜色为 3 的方块掉落,形成图 3 所示的局面。

输入格式

共 6 行。

第一行为一个正整数 n,表示要求游戏通关的步数。

接下来的 5 行,描述 7×5 的游戏界面。每行若干个整数,每两个整数之间用一个空格隔开,每行以一个 0 结束,自下向上表示每竖列方块的颜色编号(颜色不多于 10 种,从 1 开始顺序编号,相同数字表示相同颜色)。

输入数据保证初始棋盘中没有可以消除的方块。

输出格式

如果有解决方案,输出 n 行,每行包含 3 个整数 x,y,g,表示一次移动,每两个整数之间用一个空格隔开,其中 (x,y) 表示要移动的方块的坐标,g 表示移动的方向,1 表示向右移动,-1表示向左移动。注意:多组解时,按照 x 为第一关键字,y 为第二关键字,1 优先于 -1,给出一组字典序最小的解。游戏界面左下角的坐标为 (0,0)。

如果没有解决方案,输出一行 -1

说明/提示

【数据范围】

对于 30% 的数据,初始棋盘上的方块都在棋盘的最下面一行;

对于 100% 的数据,0<n≤5。

题解

大题思路

本题是一道模拟题,可以使用BFS+回溯。按照题目给出的模拟规则对每一种可能性进行尝试,最后得出最小值。

关键函数

1.allclear函数,作用:判断棋盘是否全部清空

bool allclear(){for(int i=0;i<7;i++){for(int j=0;j<5;j++){if(chess[i][j]!=0)  return 0;}}return 1;
}

2.fall函数,作用:让每个数字都掉到最底部

void fall(){for(int i=0;i<7;i++){for(int j=0;j<5;j++){int x=i;while(x>0&&chess[x-1][j]==0){swap(chess[x][j],chess[x-1][j]);x--;}}}return ;
}

3.vanish函数,作用:判断那些数字可以消失

bool vanish(){         fall();bool fg=0,canv[10][10]={0};for(int i=0;i<7;i++){for(int j=0;j<5;j++){if(chess[i][j]==0)  continue;if(j>=1&&j<=3&&chess[i][j-1]==chess[i][j]&&chess[i][j+1]==chess[i][j]){fg=1;canv[i][j-1]=canv[i][j]=canv[i][j+1]=1;}if(i>=1&&i<=5&&chess[i-1][j]==chess[i][j]&&chess[i+1][j]==chess[i][j]){fg=1;canv[i-1][j]=canv[i][j]=canv[i+1][j]=1;}}}for(int i=0;i<7;i++){for(int j=0;j<5;j++)  if(canv[i][j])  chess[i][j]=0;}fall();return fg;
} 

4.update函数,作用:反复调用vanish函数,直到没有可以消失的数字

void update(int dir,int i,int j){swap(chess[i][j],chess[i][j+dir]);while(1){if(vanish()==0)  break;}return ;
}

5.bfs函数,作用:枚举所有可能的操作

void dfs(int stp){if(flag==1)  return ;if(stp==n+1){if(allclear()){flag=1;for(int i=1;i<=n;i++){cout<<step[i][1]<<" "<<step[i][2]<<" "<<step[i][3]<<endl;}}return ;}int last[10][10];for(int k=0;k<7;k++){for(int l=0;l<5;l++)  last[k][l]=chess[k][l];}for(int j=0;j<5;j++){for(int i=0;i<7;i++){if(chess[i][j]==0)  continue;if(j<4&&chess[i][j]!=chess[i][j+1]){step[stp][1]=j,step[stp][2]=i,step[stp][3]=1;update(1,i,j);dfs(stp+1);step[stp][1]=0,step[stp][2]=0,step[stp][3]=0;for(int k=0;k<7;k++){for(int l=0;l<5;l++)  chess[k][l]=last[k][l];}} if(j>0&&chess[i][j]!=chess[i][j-1]){step[stp][1]=j,step[stp][2]=i,step[stp][3]=-1;update(-1,i,j);dfs(stp+1);step[stp][1]=0,step[stp][2]=0,step[stp][3]=0;for(int k=0;k<7;k++){for(int l=0;l<5;l++)  chess[k][l]=last[k][l];}}}}return ;
}

完整代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool flag=0;
int n,chess[10][10],step[10][10];
bool allclear(){for(int i=0;i<7;i++){for(int j=0;j<5;j++){if(chess[i][j]!=0)  return 0;}}return 1;
}
void fall(){for(int i=0;i<7;i++){for(int j=0;j<5;j++){int x=i;while(x>0&&chess[x-1][j]==0){swap(chess[x][j],chess[x-1][j]);x--;}}}return ;
}
bool vanish(){         fall();bool fg=0,canv[10][10]={0};for(int i=0;i<7;i++){for(int j=0;j<5;j++){if(chess[i][j]==0)  continue;if(j>=1&&j<=3&&chess[i][j-1]==chess[i][j]&&chess[i][j+1]==chess[i][j]){fg=1;canv[i][j-1]=canv[i][j]=canv[i][j+1]=1;}if(i>=1&&i<=5&&chess[i-1][j]==chess[i][j]&&chess[i+1][j]==chess[i][j]){fg=1;canv[i-1][j]=canv[i][j]=canv[i+1][j]=1;}}}for(int i=0;i<7;i++){for(int j=0;j<5;j++)  if(canv[i][j])  chess[i][j]=0;}fall();return fg;
}
void update(int dir,int i,int j){swap(chess[i][j],chess[i][j+dir]);while(1){if(vanish()==0)  break;}return ;
}
void dfs(int stp){if(flag==1)  return ;if(stp==n+1){if(allclear()){flag=1;for(int i=1;i<=n;i++){cout<<step[i][1]<<" "<<step[i][2]<<" "<<step[i][3]<<endl;}}return ;}int last[10][10];for(int k=0;k<7;k++){for(int l=0;l<5;l++)  last[k][l]=chess[k][l];}for(int j=0;j<5;j++){for(int i=0;i<7;i++){if(chess[i][j]==0)  continue;if(j<4&&chess[i][j]!=chess[i][j+1]){step[stp][1]=j,step[stp][2]=i,step[stp][3]=1;update(1,i,j);dfs(stp+1);step[stp][1]=0,step[stp][2]=0,step[stp][3]=0;for(int k=0;k<7;k++){for(int l=0;l<5;l++)  chess[k][l]=last[k][l];}} if(j>0&&chess[i][j]!=chess[i][j-1]){step[stp][1]=j,step[stp][2]=i,step[stp][3]=-1;update(-1,i,j);dfs(stp+1);step[stp][1]=0,step[stp][2]=0,step[stp][3]=0;for(int k=0;k<7;k++){for(int l=0;l<5;l++)  chess[k][l]=last[k][l];}}}}return ;
}
int main(){cin>>n;for(int j=0;j<5;j++){int tmp,i=0;while(cin>>tmp){if(tmp==0)  break;chess[i++][j]=tmp;}}dfs(1);if(flag==0)   cout<<-1;return 0;
}

洛谷P1312 [NOIP2011 提高组] Mayan 游戏 题解相关推荐

  1. 信息学奥赛一本通 1118:铺地毯 | 1863:【11NOIP提高组】铺地毯 | OpenJudge NOI 1.9 14 | 洛谷 P1003 [NOIP2011 提高组] 铺地毯

    [题目链接] ybt 1118:铺地毯 ybt 1863:[11NOIP提高组]铺地毯 OpenJudge NOI 1.9 14:铺地毯 洛谷 P1003 [NOIP2011 提高组] 铺地毯 [题目 ...

  2. 洛谷P1080 [NOIP2012 提高组] 国王游戏(贪心,高精度)

    [题目描述] 恰逢HHH国国庆,国王邀请nnn位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这nnn位大臣排成一排,国王站在队伍 ...

  3. 洛谷P1080 [NOIP2012 提高组] 国王游戏

    这是我的第一版,超级简单,但有个点ac不掉,想了半天才发现我理解错那个规律了 struct people{int a,b;bool operator <(const people x) cons ...

  4. 洛谷 P1070 [NOIP2009 普及组] 道路游戏 题解

    题目描述 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有 �n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依次将这 �n 个机器人工 ...

  5. 信息学奥赛一本通 1844:【06NOIP提高组】金明的预算方案 | 洛谷 P1064 [NOIP2006 提高组] 金明的预算方案

    [题目链接] ybt 1844:[06NOIP提高组]金明的预算方案 洛谷 P1064 [NOIP2006 提高组] 金明的预算方案 [题目考点] 1. 动态规划:分组背包 2. 动态规划:依赖背包 ...

  6. 信息学奥赛一本通 1890:【15NOIP提高组】跳石头 | 洛谷 P2678 [NOIP2015 提高组] 跳石头

    [题目链接] ybt 1890:[15NOIP提高组]跳石头 洛谷 P2678 [NOIP2015 提高组] 跳石头 ybt 1247:河中跳房子 OpenJudge NOI 1.11 10:河中跳房 ...

  7. 信息学奥赛一本通 1970:【15NOIP普及组】扫雷游戏 | OpenJudge NOI 1.8 14:扫雷游戏地雷数计算 | 洛谷 P2670 [NOIP2015 普及组] 扫雷游戏

    [题目链接] ybt 1970:[15NOIP普及组]扫雷游戏 OpenJudge NOI 1.8 14:扫雷游戏地雷数计算 洛谷 P2670 [NOIP2015 普及组] 扫雷游戏 [题目考点] 1 ...

  8. 信息学奥赛一本通 1848:【07NOIP提高组】字符串的展开 | OpenJudge NOI 1.7 35:字符串的展开 | 洛谷 P1098 [NOIP2007 提高组] 字符串的展开

    [题目链接] ybt 1848:[07NOIP提高组]字符串的展开 OpenJudge NOI 1.7 35:字符串的展开 洛谷 P1098 [NOIP2007 提高组] 字符串的展开 [题目考点] ...

  9. 信息学奥赛一本通 1855:【09NOIP提高组】潜伏者 | OpenJudge NOI 1.7 11:潜伏者 | 洛谷 P1071 [NOIP2009 提高组] 潜伏者

    [题目链接] ybt 1855:[09NOIP提高组]潜伏者 OpenJudge NOI 1.7 11:潜伏者 洛谷 P1071 [NOIP2009 提高组] 潜伏者 [题目考点] 1. 字符串 2. ...

最新文章

  1. 算法设计与分析第5章 回溯法(二)【回溯法应用】
  2. 看着像学生,实为博导、教授!发过4篇CNS,刚刚又获重要大奖
  3. 解决maven构建webapp index.jsp报错问题
  4. 统计学习方法笔记(一)-k近邻算法原理及python实现
  5. LNMP - Nginx配置防盗链
  6. sku属性组合小例子
  7. 田志刚:为什么要尊重老师?
  8. Altair PollEx 2020中文版
  9. mysql数据库保存中文乱码解决参考方案
  10. 不固定图片宽高瀑布流_APP设计学习:瀑布流式的产品UI设计
  11. Stack与queue的底层实现、区别。
  12. python for循环 内存_Python for循环中的内存错误
  13. html简单网页代码 案例_HTML+CSS静态网页练习案例(转动的八卦图)
  14. js/vue两张图片合成一张画布
  15. 【《Real-Time Rendering 3rd》 提炼总结】(五) 第六章 · 纹理贴图及相关技术 The Texturing
  16. 有一种单身叫宁缺勿滥 -- 纪念百年神棍节
  17. C_CAPM模型(上)
  18. [360] 《如何保持电力接触网与受电弓亲密接触》
  19. 超详细的 Wireshark 使用教程
  20. 想要做好自媒体?大周给你分享几点心得

热门文章

  1. scp 报错: Permission denied, please try again(publickey,password)
  2. 前端面试知识点整理——项目整理
  3. 2019CCPC网络赛 1002 HDU 6703(权值线段树)
  4. 住建部就《“多规合一”业务协同平台技术标准》征求意见
  5. 15KW电动机380V及220V时的电流分别为多少
  6. 官网客服不在线?看上海交大教育集团如何用在线客服功能快速响应客户!
  7. JS输出、语句和注释方法
  8. Flutter系列(三):Flutter挑战复杂页面!视频编辑页面来袭。
  9. c语言程序10进制转8进制数,C ++程序将十进制数转换为八进制
  10. Weblogic漏洞利用总结