[noip2011 d1t3] Mayan游戏

无脑码农题==

烦的是很多细节,把几个主要过程分开写,化整为零会清楚很多

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<algorithm>
  5 using namespace std;
  6 #define mxcol 12
  7 int map[10][10];
  8 int goal;
  9 struct data{
 10     int x,y,w;
 11 }ans[10];
 12 int read(){
 13     int x=0;
 14     char ch=getchar();
 15     while (ch<‘0‘||ch>‘9‘) ch=getchar();
 16     while (ch>=‘0‘&&ch<=‘9‘){
 17         x=x*10+ch-‘0‘;
 18         ch=getchar();
 19     }
 20     return x;
 21 }
 22 bool empty(){
 23     for (int i=0;i<5;i++)
 24       for (int j=0;j<7;j++)
 25         if (map[i][j]) return 0;
 26     return 1;
 27 }
 28 void DROP(){
 29     int time[10][10];
 30     memset(time,-1,sizeof(time));
 31     for (int x=0;x<5;x++){
 32         int num=0;
 33         for (int y=0;y<7;y++)
 34           if (map[x][y])
 35             time[x][num++]=y;
 36     }
 37     for(int x=0;x<5;x++)
 38       for (int y=0;y<7;y++)
 39         map[x][y]=time[x][y]==-1?0:map[x][time[x][y]];
 40 }
 41 bool CLEAR(){
 42     bool flag=0;
 43     //横
 44     for (int i=0;i<3;i++)
 45       for (int j=0;j<7;j++)
 46         if (map[i][j]){
 47             int x;
 48             for (x=i;x+1<5&&map[i][j]==map[x+1][j];x++);
 49             if (x-i>=2){
 50                 int nx;
 51                 for (nx=i;nx<=x;nx++){
 52                     int up=j,down=j;
 53                     while (up+1<7&&map[nx][up+1]==map[i][j]) up++;
 54                     while (down-1>=0&&map[nx][down-1]==map[i][j]) down--;
 55                     if (up-down>=2){
 56                         for (int ny=down;ny<=up;ny++)
 57                           map[nx][ny]=0;
 58                     }
 59                 }
 60                 for (nx=i;nx<=x;nx++)
 61                   map[nx][j]=0;
 62                 flag=1;
 63             }
 64         }
 65     //竖
 66     for (int i=0;i<5;i++)
 67       for (int j=0;j<5;j++)
 68         if (map[i][j]){
 69             int y;
 70             for (y=j;y+1<7&&map[i][y+1]==map[i][j];y++);
 71             if (y-j>=2){
 72                 int ny;
 73                 for (ny=j;ny<=y;ny++){
 74                     int left=i,right=i;
 75                     while (left>0&&map[left-1][ny]==map[i][j]) left--;
 76                     while (right+1<7&&map[right+1][ny]==map[i][j]) right++;
 77                     if (right-left>=2){
 78                         for (int nx=left;nx<=right;nx++)
 79                         map[nx][ny]=0;
 80                     }
 81                 }
 82                 for (ny=j;ny<=y;ny++)
 83                   map[i][ny]=0;
 84                 flag=1;
 85             }
 86         }
 87     return flag;
 88 }
 89 void dfs(int step){
 90     if (step>goal){
 91         if (empty()){//判断游戏结束
 92             for (int i=1;i<=goal;i++)
 93               if (ans[i].w)
 94                 printf("%d %d -1\n",ans[i].x+1,ans[i].y);
 95               else
 96                 printf("%d %d 1\n",ans[i].x,ans[i].y);
 97             exit(0);
 98         }
 99         return;
100     }
101
102     int time[mxcol];
103     memset(time,0,sizeof(time));
104     for (int i=0;i<5;i++)
105       for (int j=0;j<7;j++)
106         time[map[i][j]]++;
107     for (int i=1;i<=10;i++)
108       if (time[i]!=0&&time[i]<3) return;//剪枝:当某种颜色块数小于3时必然无解
109
110     for (int x=0;x<4;x++)//优先向右换;按字典序枚举
111       for (int y=0;y<7;y++)
112         if (map[x][y]!=map[x+1][y]){//两方块颜色不同时才交换
113              ans[step].x=x,ans[step].y=y;
114              ans[step].w=!map[x][y];//枚举的时候是从左往右,但也可能左边空右边有方块,此时标记将右边的方块向左移动
115              int tmp[10][10];
116              memcpy(tmp,map,sizeof(tmp));
117              swap(map[x][y],map[x+1][y]);
118
119              DROP();
120              while (CLEAR()) DROP();
121              //两个主要过程:上面的方块掉落;合法的方块消去
122              dfs(step+1);
123
124              ans[step].x=0,ans[step].y=0;
125              ans[step].w=0;
126              memcpy(map,tmp,sizeof(map));
127         }
128 }
129 int main(){
130     goal=read();
131     memset(map,0,sizeof(map));
132     for (int i=0;i<5;i++){
133         for (int j=0;;j++){
134             int u=read();
135             if (!u) break;
136             map[i][j]=u;
137         }
138     }
139     dfs(1);
140     printf("-1\n");
141     return 0;
142 } 

时间: 2024-08-22 20:18:34

[noip2011 d1t3] Mayan游戏的相关文章

NOIp2011 mayan游戏

传送门 题目描述 Mayan puzzle 是最近流行起来的一个游戏.游戏界面是一个 7行 5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定的步数内消除所有的方块,消除方块的规则如下: 1.  每步移动可以且仅可以沿横向(即向左或向右)拖动某一方块一格:当拖动这一方块时,如果拖动后到达的位置(以下称目标位置)也有方块,那么这两个方块将交 换位置(参见输入输出样例说明中的图 6 到图 7):如果目标位置上没有方块,那么被拖动的方

【noip2011】【codevs1136】Mayan游戏

3.Mayan 游戏(mayan.cpp/c/pas)[问题描述]Mayan puzzle 是最近流行起来的一个游戏.游戏界面是一个7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定的步数内消除所有的方块,消除方块的规则如下:1.每步移动可以且仅可以沿横向(即向左或向右)拖动某一方块一格:当拖动这一方块时,如果拖动后到达的位置(以下称目标位置)也有方块,那么这两个方块将交换位置(参见输入输出样例说明中的图6 到图7):如果

洛谷P1312 [NOIOP2011提高组 Day1T3]Mayan游戏

Mayan游戏 题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定的步数内消除所有的方块,消除方块的规则如下: 1 .每步移动可以且仅可以沿横向(即向左或向右)拖动某一方块一格:当拖动这一方块时,如果拖动后到达的位置(以下称目标位置)也有方块,那么这两个方块将 交换位置(参见输入输出样例说明中的图6 到图7 ):如果目标位置上没有方块,那么被拖动的

洛谷 P1312 Mayan游戏

P1312 Mayan游戏 题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定的步数内消除所有的方块,消除方块的规则如下: 1 .每步移动可以且仅可以沿横向(即向左或向右)拖动某一方块一格:当拖动这一方块时,如果拖动后到达的位置(以下称目标位置)也有方块,那么这两个方块将交换位置(参见输入输出样例说明中的图6 到图7 ):如果目标位置上没有方块,那

noip提高组2011 Mayan游戏

Mayan游戏 描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个7行5列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.**游戏通关是指在规定的步数内消除所有的方块,**消除方块的规则如下: 1.每步移动可以且仅可以沿横向(即向左或向右)拖动某一方块一格:当拖动这一方块时,如果拖动后到达的位置(以下称目标位置)也有方块,那么这两个方块将交换位置(参见图6到图7):如果目标位置上没有方块,那么被拖动的方块将从原来的竖列中抽出,并从

$Mayan$游戏

\(Mayan\)游戏 好啊,一年(半年)来的梦魇,终于结束了. 其实我从来没料到整体竟然会如此暴力--做的时候机房里冷得很,感觉晕晕乎乎地做完了,晕晕乎乎地调了好久,晕晕乎乎地听(看了题解的)\(qcr\)给我讲怎么优化代码量,怎么剪枝. 每次搜索要保留本次的状态,这是比较好想的,我也成功的想到了.但是问题是我们不能单纯地用一个二维数组来\(copy\),需要记录步数,不然就会错误\(copy\_back\).于是最终我们需要一个三维数组来记录.后半段是\(qcr\)告诉我的. 大概就是--我

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

P1312 Mayan游戏 这道题跟斗地主都是大模拟啊!稍微挂一点可能就爆零了! 图肯定能存,直接二维数组扔进去即可. 然后套dfs模板,搜索就先照那样搜. 核心操作有两个:一个是判断那些块可以消掉,一个是把那些可以消的消了. 第一个操作的核心代码是这样的: for(int i = 1; i <= 5; i++) { for(int j = 1; j <= 7; j++) { if(G[i][j] && i - 1 >= 1 && i + 1 <=

刷题总结——mayan游戏(NOIP2011提高组day2T3)

题目: 题目背景 NOIP2011提高组 DAY1 试题. 题目描述 Mayan puzzle 是最近流行起来的一个游戏.游戏界面是一个 7 行 5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定的步数内消除所有的方块,消除方块的规则如下: 1.每步移动可以且仅可以沿横向(即向左或向右)拖动某一方块一格:当拖动这一方块时,如果拖动后到达的位置(以下称目标位置)也有方块,那么这两个方块将交换位置(参见输入输出样例说明中的图6 到图

NOIP2011 Mayan游戏 题解

描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个7行5列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定的步数内消除所有的方块,消除方块的规则如下: 1.每步移动可以且仅可以沿横向(即向左或向右)拖动某一方块一格:当拖动这一方块时,如果拖动后到达的位置(以下称目标位置)也有方块,那么这两个方块将交换位置(参见图6到图7):如果目标位置上没有方块,那么被拖动的方块将从原来的竖列中抽出,并从目标位置上掉落(直到不悬