题解:搜索+模拟

剪枝:

最优性剪枝:x从小到大,y从小到大,第一次搜到的就是字典序最小

的最优解。

最优性剪枝:把一个格子和左边格子交换,和左边格子和右边格

子交换是等价的,显然让左边格子和右边交换更优。

可行性剪枝:如果当前格子某个颜色个数为1或者2return 一定消不去。

最优性剪枝:相同颜色格子交换并没有什么卵用,当左边是空时和左边交换

几个操作

(1)down()函数 目的是为了让腾空的格子落下

(2)xiao()函数 目的是让三个相同颜色的格子消去

(3)check()函数 当前颜色是否都被消去了

错因:不是蠢是弱呀...,down函数写错了,还有tmp[][]不能设成

全局变量,否则回溯不了....md...orz

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 20
using namespace std;
int n;
int map[maxn][maxn],re[maxn][maxn],ans[maxn][maxn],cnt[maxn];

void read(){
    scanf("%d",&n);
    for(int i=1;i<=5;i++){
        int nu=0,x;
        while(1){
            scanf("%d",&x);
            if(!x)break;
            map[i][++nu]=x;
        }
    }
}

bool check(){
    for(int i=1;i<=5;i++)
     for(int j=1;j<=7;j++)
      if(map[i][j])return false;
    return true;
}

void down(){
    for(int i=1;i<=5;i++){
        int nu=0,t;
        for(int j=1;j<=7;j++){
          //  if(map[i][j])map[i][++nu]=map[i][j],map[i][j]=0;
          //留住上面沙茶的一行,最后map[][]竟然清0了、
          if(map[i][j]){t=map[i][j];map[i][j]=0;map[i][++nu]=t;} 
        }
    }
}

bool xiao(){
    bool flag=false;
    memset(re,0,sizeof(re));
    for(int i=1;i<=5;i++){
        for(int j=1;j<=7;j++){
            if(map[i][j]&&map[i][j]==map[i][j-1]&&map[i][j]==map[i][j+1])
            flag=true,re[i][j]=re[i][j-1]=re[i][j+1]=true;
            if(map[i][j]&&map[i][j]==map[i+1][j]&&map[i][j]==map[i-1][j])
            flag=true,re[i][j]=re[i+1][j]=re[i-1][j]=true;
        }
    }
    for(int i=1;i<=5;i++)
     for(int j=1;j<=7;j++)
      if(re[i][j])map[i][j]=0;
    return flag;
}

void dfs(int x){
    if(x==n+1){
        if(check()){
            for(int i=1;i<=n;i++)
             printf("%d %d %d\n",ans[i][1]-1,ans[i][2]-1,ans[i][3]);
            exit(0);        
        }
        return;
    }
    int tmp[20][20];memset(cnt,0,sizeof(cnt));
    for(int i=1;i<=5;i++)for(int j=1;j<=7;j++)tmp[i][j]=map[i][j],cnt[map[i][j]]++;
    for(int i=1;i<=10;i++)if(cnt[i]==1||cnt[i]==2)return;
    for(int i=1;i<=5;i++){
        for(int j=1;j<=7;j++){
        if(map[i][j]==0)break;
            if(map[i][j]!=map[i+1][j]&&i!=5){
                swap(map[i][j],map[i+1][j]);
                ans[x][1]=i,ans[x][2]=j,ans[x][3]=1;
                down();while(xiao())down();
                dfs(x+1);
                for(int i=1;i<=5;i++)for(int j=1;j<=7;j++)map[i][j]=tmp[i][j];
            }
            if(map[i-1][j]==0&&i!=1){
                swap(map[i][j],map[i-1][j]);
                ans[x][1]=i,ans[x][2]=j,ans[x][3]=-1;
                down();while(xiao())down();
                dfs(x+1);
                for(int i=1;i<=5;i++)for(int j=1;j<=7;j++)map[i][j]=tmp[i][j];
            }
        }
    }
}

int main(){
    read();dfs(1);
    puts("-1");
    return 0;
}
AC

相关文章:

  • 2021-10-01
  • 2022-12-23
  • 2021-08-04
  • 2021-11-13
  • 2022-01-24
猜你喜欢
  • 2021-06-06
  • 2022-02-18
  • 2020-03-22
  • 2021-08-02
  • 2022-12-23
相关资源
相似解决方案