版权声明:本文为DyingShu原创文章,转载请注明出处哦。 https://blog.csdn.net/DyingShu/article/details/82054079
题解:爆搜+剪枝
要注意以下几点:
- 向右搜时,若颜色一样则不搜
- 向左搜时,若不是空格,则不搜(因为此时它左边的方块已经向右搜索过了)
- 可以把搜索过程想象成一颗搜索树,这样只用开与这棵树的深度成正比的状态数组
- DFS时先考虑右移,因为右移优先度比左移高
具体见代码吧~
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN = 11;
int n, Total;
int Now_Plate[MAXN][MAXN][MAXN]; //第i层 第i列 高度为j
bool tag[MAXN][MAXN];
int Ans[MAXN][3];
inline int read(){
int k = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') f = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){k = k*10 + ch - '0'; ch = getchar();}
return k * f;
}
void Fall_Down(int u){ //处理Now_Plate的掉落
for(int i = 1; i <= 5; i++){
int temp = 0;
for(int j = 1; j <= 7; j++){
if(Now_Plate[u][i][j]){
Now_Plate[u][i][++temp] = Now_Plate[u][i][j];
}
}
for(int j = temp + 1; j <= 7; j++){
Now_Plate[u][i][j] = 0;
}
}
}
void Clear(int u){ //对Now_Plate进行消除
for(bool flag = true; flag;){
flag = false; Fall_Down(u); //记录消除
for(int i = 1; i <= 5; i++){
for(int j = 1; j <= 7; j++){
if(!Now_Plate[u][i][j]) continue;
//处理横着的
if(i <= 3){
if(Now_Plate[u][i][j] == Now_Plate[u][i + 1][j] && Now_Plate[u][i][j] == Now_Plate[u][i + 2][j]){
flag = tag[i][j] = tag[i + 1][j] = tag[i + 2][j] = true;
}
}
//处理竖着的
if(j <= 5){
if(Now_Plate[u][i][j] == Now_Plate[u][i][j + 1] && Now_Plate[u][i][j] == Now_Plate[u][i][j + 2]){
flag = tag[i][j] = tag[i][j + 1] = tag[i][j + 2] = true;
}
}
}
}
for(int i = 1; i <= 5; i++){
for(int j = 1; j <= 7; j++){
if(tag[i][j]){
Now_Plate[u][i][j] = tag[i][j] = 0;
}
}
}
}
}
bool dfs(int u){ //第几步
// Total++;
for(int i = 1; i <= 5; i++){
for(int j = 1; j <= 7; j++){
Now_Plate[u][i][j] = Now_Plate[u - 1][i][j];
}
}
Clear(u);
if(u > n){
for(int i = 1; i <= 5; i++){
if(Now_Plate[u][i][1]) return false;
}
return true;
}
for(int i = 1; i <= 5; i++){
for(int j = 1; j <= 7; j++){
if(!Now_Plate[u][i][j]) continue;
//试图向右
if(i < 5 && Now_Plate[u][i][j] != Now_Plate[u][i + 1][j]){//不一样才有意义
Ans[u][0] = i - 1, Ans[u][1] = j - 1, Ans[u][2] = 1;
swap(Now_Plate[u][i][j], Now_Plate[u][i + 1][j]);
if(dfs(u + 1)) return true;
swap(Now_Plate[u][i][j], Now_Plate[u][i + 1][j]);
}
//试图向左
if(i > 1 && !Now_Plate[u][i - 1][j]){
Ans[u][0] = i - 1, Ans[u][1] = j - 1, Ans[u][2] = -1;
swap(Now_Plate[u][i][j], Now_Plate[u][i - 1][j]);
if(dfs(u + 1)) return true;
swap(Now_Plate[u][i][j], Now_Plate[u][i - 1][j]);
}
}
}
return false;
}
int main(){
freopen("in.txt", "r", stdin);
n = read();
for(int i = 1; i <= 5; i++){
for(int j = 1; j <= 8; j++){
int x = read();
if(!x) break;
Now_Plate[0][i][j] = x;
}
}
if(dfs(1)){
for(int i = 1; i <= n; i++){
for(int j = 0; j < 3; j++){
printf("%d ", Ans[i][j]);
}
printf("\n");
}
}
else printf("-1");
// printf("\n");
// printf("Total = %d", Total);
return 0;
}