描述

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

1、每步移动可以且仅可以沿横向(即向左或向右)拖动某一方块一格:当拖动这一方块时,如果拖动后到达的位置(以下称目标位置)也有方块,那么这两个方块将交换位置(参见图6到图7);如果目标位置上没有方块,那么被拖动的方块将从原来的竖列中抽出,并从目标位置上掉落(直到不悬空,参见图1和图2);

2、任一时刻,如果在一横行或者竖列上有连续三个或者三个以上相同颜色的方块,则它们将立即被消除(参见图1到图3)。

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

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

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

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

格式

输入格式

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

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

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

输出格式

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

样例1

样例输入1[复制]

3
1 0
2 1 0
2 3 4 0
3 1 0
2 4 3 4 0

样例输出1[复制]

2 1 1
3 1 1
3 0 1

限制

3s

提示

  超复杂爆搜,没别的法了。。。。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxx=10,maxy=20,maxc=20;
  4 int n,c;//n表示步数,c表示方块颜色数
  5 int a[maxx][maxy];//存图
  6 int cnt[maxc];//记录每种颜色方块的个数
  7 bool f[maxx][maxy];
  8 int ans[maxx][3];
  9
 10 void fall(int x){//第 x行下落构图
 11     for(int i=0;i<7;i++){
 12         if(a[x][i]==0){
 13             int j=i+1;
 14             while(j<7&&a[x][j]==0)
 15                 j++;
 16             if(j==7)
 17                 return;
 18             else swap(a[x][i],a[x][j]);
 19         }
 20     }
 21 }
 22
 23 bool clear(){
 24
 25     bool flag=false;
 26     for(int i=0;i<5;i++){//横坐标
 27         for(int j=0;j<7;j++){//纵坐标
 28             if(a[i][j]==0)
 29                 continue;
 30             if(i<3&&a[i][j]==a[i+1][j]&&a[i][j]==a[i+2][j]){//横向消
 31                 f[i][j]=true;
 32                 f[i+1][j]=true;
 33                 f[i+2][j]=true;
 34             }
 35             if(j<5&&a[i][j]==a[i][j+1]&&a[i][j]==a[i][j+2]){//纵向消
 36                 f[i][j]=true;
 37                 f[i][j+1]=true;
 38                 f[i][j+2]=true;
 39             }
 40         }
 41     }
 42
 43     for(int i=0;i<5;i++){
 44         for(int j=0;j<7;j++){
 45             if(f[i][j]==true){//(i,j)需要被消掉
 46                 flag=true;
 47                 cnt[a[i][j]]--;//颜色减少
 48                 a[i][j]=0;
 49                 f[i][j]=false;
 50             }
 51         }
 52     }
 53
 54     for(int i=0;i<5;i++)
 55         fall(i);//消完之后再下落
 56
 57     return flag;//返回true说明还有可能继续消
 58 }
 59
 60 int check(){//输出方块颜色最少的那个颜色个数
 61     int minc=0;
 62     for (int i=1;i<=c;i++){
 63         if(cnt[i]!=0){
 64             if (minc==0||minc>cnt[i]){
 65                 minc=cnt[i];
 66             }
 67         }
 68     }
 69     return minc;
 70 }
 71
 72 void print(){//输出答案
 73
 74     for (int i = 1; i <= n; i++)
 75             printf("%d %d %d\n", ans[i][0], ans[i][1], ans[i][2]);
 76
 77    exit(0);//结束程序
 78 }
 79 void dfs(int move){//move 移动步数
 80
 81     int mem[maxx][maxy];
 82     int memc[maxc];
 83     memcpy(mem,a,sizeof(a));
 84     memcpy(memc,cnt,sizeof(cnt));
 85
 86     for(int i=0;i<5;i++){//横坐标
 87         for(int j=0;a[i][j]!=0&&j<7;j++){//纵坐标
 88             for (int k=1;k>=-1;k-=2){//右移左移两种情况,先算右移
 89                 if(i+k>=0&&i+k<5){//判断边界
 90                     if ((k==-1&&a[i-1][j]!=0)||a[i][j]==a[i+k][j])//如果左边有方块或者相邻的方块同色,不需考虑
 91                         continue;
 92
 93                      ans[move][0]=i;//记录移动信息
 94                     ans[move][1]=j;
 95                     ans[move][2]=k;
 96                      swap(a[i][j], a[i+k][j]);//交换
 97
 98                      fall(i);//处理交换后的影响
 99                     fall(i+k);
100
101                     while (clear()==true);//消去再组合
102                      int tmp=check();//tmp是当前颜色最少的方块的个数
103                      if(move==n){//n步
104                            if(tmp==0)//方块完
105                             print();//满足条件,输出
106                      }
107                     else if(tmp>2)//找下一步
108                         dfs(move+1);
109
110                     memcpy(a,mem,sizeof(mem));//相当于回溯,把操作之前的恢复原状
111                     for (int i = 1; i <= c; i++)
112                       cnt[i] = memc[i];
113                 }
114              }
115         }
116     }
117
118 }
119
120 int main(){
121     scanf("%d", &n);
122     memset(a, 0, sizeof(a));
123     memset(cnt, 0, sizeof(cnt));
124     memset(ans, 0, sizeof(ans));
125     memset(f, 0, sizeof(f));
126     c = 0;
127     int tmp;
128     for (int i = 0; i < 5; i++)
129         for (int j = 0; j <= 7; j++){
130             scanf("%d", &tmp);
131             if (tmp == 0)
132                 break;
133             a[i][j] = tmp;
134             c = max(c, tmp);
135             cnt[tmp]++;//每种方块的数量
136         }
137     dfs(1);
138     printf("-1\n");//能走到这一步说明没走print(),即消不完
139     return 0;
140 }

转载于:https://www.cnblogs.com/CXCXCXC/p/4783328.html

NOIP Mayan游戏相关推荐

  1. [Luogu 1312] noip11 Mayan游戏

    [Luogu 1312] noip11 Mayan游戏 Problem: Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即 ...

  2. P1312 Mayan游戏 [模拟][搜索]

    P1312 Mayan游戏 这道题跟斗地主都是大模拟啊!稍微挂一点可能就爆零了! 图肯定能存,直接二维数组扔进去即可. 然后套dfs模板,搜索就先照那样搜. 核心操作有两个:一个是判断那些块可以消掉, ...

  3. 洛谷P1312 Mayan游戏

    P1312 Mayan游戏 题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他 ...

  4. Noip2011 dayt3 Mayan游戏

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

  5. 洛谷P1312 [NOIP2011 提高组] Mayan 游戏 题解

    题目描述 Mayan puzzle 是最近流行起来的一个游戏.游戏界面是一个7 行 5×5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指 ...

  6. 2463: [中山市选2009]谁能赢呢? Codeforces Round #429 (Div. 2) B. Godsend noip三国游戏...

    Description 小明和小红经常玩一个博弈游戏.给定一个n×n的棋盘,一个石头被放在棋盘的左上角.他们轮流移动石头.每一回合,选手只能把石头向上,下,左,右四个方向移动一格,并且要求移动到的格子 ...

  7. 题解 Mayan游戏

    @luogu 搜索剪枝题,每一次暴力下落,暴力消除 #include<cstdio> #include<cstring> #include<algorithm> # ...

  8. [贪心][高精度][NOIP]国王游戏

    题目梗概 有n个大臣,他们可以拿到他们之前所有人左手数的乘积除以他的右手,问是否能通过调换位置来使拿钱最多的大臣拿的钱最少. 思考 贪心证明: 设相邻的两个人$i, i + 1$.设$A[i] \ti ...

  9. NOIP 2011 Day 1

    NOIP 2011 Day 1 tags: NOIP 搜索 categories: 信息学竞赛 总结 铺地毯 选择客栈 Mayan游戏 铺地毯 Solution 因为只会询问一个点被谁覆盖, 而且后面 ...

最新文章

  1. 自然语言处理期末复习(6)话题模型
  2. 服务器中有两个R文件夹,一台服务器中配置多个git sshkey
  3. oracle em agent,ORACLE 11G EM 配置命令及问题处理
  4. 偶尔所得代码片(进程和锁相关)
  5. 买断式软件逐渐向订阅式软件发展,是不是资本想一直割韭菜?
  6. MapXtreme 根据名称搜索图元
  7. java毕业设计 - vue外卖的点餐系统
  8. (c语言详解)06-图3 六度空间 (30分)(详细解释)
  9. TreeView 右键菜单
  10. 6. LaTeX 参考文献的排版与引用
  11. 无人机2018发展趋势:数据采集 空中出租车受热捧 | 行业
  12. 人工智能:《时代周刊》2019年度100大最佳发明榜单发布!
  13. MD5校验判断文件是否一样
  14. 玉米社:单页网站怎么做seo?优化思路?
  15. 浅谈Attention机制
  16. servlet3.1规范翻译:第13章 安全
  17. 北理工通报方岱宁院士处理结果
  18. 阿龙的学习笔记---3.26---常用的各种树
  19. Objective-C基本分析法 反编译
  20. 【稳定性day5】阿里自动压测及容量规划 - 对抗流量的必杀器

热门文章

  1. Linux/U-Boot Git Repo
  2. Kafka+Storm+HDFS整合实践
  3. 回归分析中的正则化问题
  4. rhel5.5下安装awstats实现网站流量监控
  5. 在package-lock.json中指定node-mass版本+独立编译flink中的flink-runtime-web模块
  6. alink的相關資料收集
  7. 根据传递函数仿真模拟滤波器的波特图(持续更新中)
  8. 启动hbase后hregionserver没有启动
  9. Colaboratory挂载google drive的两种网盘
  10. 如何一次性复制带有markdown/mathjax/latex的博客内容