题解:搜索+模拟
剪枝:
最优性剪枝: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; }