题解:
非常暴力的一道题
因为地图比较小,枚举35块所有向左拉或者向右拉总共70种情况
输出一个字典序最小的一个答案,事实上是降低了深搜难度
按从小到大依次搜索x和y,先向右拉,再向左拉,对于每一次拉动
先交换两个方块,然后将这两列的方块全部落下,这就需要我们写一个“掉落”函数
掉落完成后,进行“清除”操作,规则跟一般的三消游戏差不多
清除操作必须将当前能消除的全部消除,另外消除完后还要将悬空的方块落下
注意落下之后还有可能继续消除,因此要用递归或者while循环直到完全不能再清除
深搜完成后,还原现场显得与平常的深搜不同,我们需要在每一层中都定义一个临时的
数组来保存原地图,然后用memcpy还原现场
掉落函数
定义一个浮标,当前行有数字时移动浮标,为0时不移动
这就可以将悬空的方块移下来了
清除函数
找所有35个方块,若左右两边或者上下的颜色相同,则将它们赋为0
然后执行掉落函数,继续消除
因为此题给了步数,边界就很好判定了,当达到规定步数并且所有方块都为0
则到达边界,并且能保证字典序最小
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<climits>
#define MAXA 10
using namespace std;
int mayan[MAXA][MAXA],n,Ans[MAXA][MAXA];
void Fall_Down(int lie) {
int cnt = -1;
for(int i=0;i<7;i++)
if(mayan[lie][i])
mayan[lie][++cnt] = mayan[lie][i];
for(int i=cnt+1;i<7;i++)
mayan[lie][i] = 0;
return;
}
void Clear() {
bool flag = true;
while(flag) {
flag = false;
int temp[10][10];
memcpy(temp,mayan,sizeof(temp));
for(int i=0;i<5;i++)
for(int j=0;j<7;j++) {
if(i >= 1 && i <= 3 && temp[i][j] && temp[i][j] == temp[i-1][j] && temp[i][j] == temp[i+1][j]) {
mayan[i][j] = 0;
mayan[i-1][j] = 0;
mayan[i+1][j] = 0;
flag = true;
}
if(j >= 1 && j <= 5 && temp[i][j] && temp[i][j] == temp[i][j-1] && temp[i][j] == temp[i][j+1]) {
mayan[i][j] = 0;
mayan[i][j-1] = 0;
mayan[i][j+1] = 0;
flag = true;
}
}
if(!flag)
return;
for(int i=0;i<5;i++)
Fall_Down(i);
}
}
void PushAns(int i,int x,int y,int type) { //更新答案
Ans[i][1] = x;
Ans[i][2] = y;
Ans[i][3] = type;
}
bool isComplete() { //判断是否全部消完
for(int i=0;i<5;i++)
for(int j=0;j<7;j++)
if(mayan[i][j])
return 0;
return 1;
}
void DFS(int step) {
if(isComplete() && step == n) {
for(int i=1;i<=step;i++)
printf("%d %d %d\n",Ans[i][1],Ans[i][2],Ans[i][3]);
exit(0);
}
if(step >= n)
return;
int temp[10][10];
memcpy(temp,mayan,sizeof(temp));
for(int i=0;i<5;i++)
for(int j=0;j<7;j++) {
if(!mayan[i][j])
continue;
if(i != 4) {
swap(mayan[i][j],mayan[i+1][j]);
Fall_Down(i);
Fall_Down(i + 1);
Clear();
PushAns(step+1,i,j,1);
DFS(step + 1);
PushAns(step+1,0,0,0);
memcpy(mayan,temp,sizeof(mayan));
}
if(i && !mayan[i-1][j]) {
swap(mayan[i][j],mayan[i-1][j]);
Fall_Down(i);
Fall_Down(i - 1);
Clear();
PushAns(step+1,i,j,-1);
DFS(step + 1);
PushAns(step+1,0,0,0);
memcpy(mayan,temp,sizeof(mayan));
}
}
}
int main() {
scanf("%d",&n);
for(int i=0;i<5;i++) {
int p = 0;
do {
cin >> mayan[i][p];
p++;
}while(mayan[i][p-1] != 0);
}
DFS(0);
}