Mayan puzzle
是最近流行起来的一个游戏。游戏界面是一个77 行 imes 5×5列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上。游戏通关是指在规定的步数内消除所有的方块,消除方块的规则如下:
1 、每步移动可以且仅可以沿横向(即向左或向右)拖动某一方块一格:当拖动这一方块时,如果拖动后到达的位置(以下称目标位置)也有方块,那么这两个方块将交换位置(参见输入输出样例说明中的图6到图7);如果目标位置上没有方块,那么被拖动的方块将从原来的竖列中抽出,并从目标位置上掉落。
Solution
注意到n非常小,所以直接暴力就好,枚举格子,先枚举向右移动,在向左移动。
有一个小剪枝,向左移动时要移动到空的位置,如果不是,那就不是最优解(右边可以动过来)。
注意读入!!!!
Code
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define R register using namespace std; int a[10][10],n,tot,bul[12]; bool tag[10][10]; struct node{ int x,y,tag; }ji[8]; inline void print(){ for(int i=1;i<=7;++i){ for(int j=1;j<=5;++j)cout<<a[i][j]<<" "; cout<<endl; } cout<<endl; } inline bool isempty(){ for(R int i=7;i>=1;--i) for(R int j=1;j<=5;++j) if(a[i][j])return 0; return 1; } inline bool isk(){ bool p=0; memset(tag,0,sizeof(tag)); for(R int j=1;j<=5;++j) for(R int i=7;i>=1;--i)if(a[i][j]){ if(a[i][j]==a[i][j+1]&&a[i][j]==a[i][j-1])tag[i][j]=tag[i][j-1]=tag[i][j+1]=1,p=1; if(a[i][j]==a[i-1][j]&&a[i][j]==a[i+1][j])tag[i][j]=tag[i-1][j]=tag[i+1][j]=1,p=1; } return p; } inline void gan(){ for(R int i=6;i>=1;--i) for(R int j=1;j<=5;++j) if(a[i][j]&&(!a[i+1][j])){ int pos=i; while(pos!=7&&a[pos][j]&&(!a[pos+1][j]))swap(a[pos][j],a[pos+1][j]),pos++; } while(isk()){ for(R int j=1;j<=5;++j) for(R int i=7;i>=1;--i)if(tag[i][j])bul[a[i][j]]--,a[i][j]=0; for(R int i=6;i>=1;--i) for(R int j=1;j<=5;++j) if(a[i][j]&&(!a[i+1][j])){ int pos=i; while(pos!=7&&a[pos][j]&&(!a[pos+1][j]))swap(a[pos][j],a[pos+1][j]),pos++; } } } void dfs(int x){ if(isempty()){ for(R int i=1;i<=tot;++i)printf("%d %d %d ",ji[i].x,ji[i].y,ji[i].tag); exit(0); } if(x>n)return; // for(R int i=1;i<=10;++i)if(bul[i]==1||bul[i]==2)return; int b[10][10],mp[12]; for(int i=1;i<=10;++i)mp[i]=bul[i]; for(R int i=1;i<=7;++i)for(R int j=1;j<=5;++j)b[i][j]=a[i][j]; for(R int j=1;j<=5;++j) for(R int i=7;i>=1;--i) if(a[i][j]){ if(a[i][j]!=a[i][j+1]&&j<5){ swap(a[i][j],a[i][j+1]); ji[++tot]=node{j-1,7-i,1}; gan(); dfs(x+1); tot--; for(R int i=1;i<=7;++i)for(R int j=1;j<=5;++j)a[i][j]=b[i][j]; for(R int i=1;i<=10;++i)bul[i]=mp[i]; } if(!a[i][j-1]&&j>1){ swap(a[i][j],a[i][j-1]); ji[++tot]=node{j-1,7-i,-1}; gan(); dfs(x+1); tot--; for(R int i=1;i<=7;++i)for(R int j=1;j<=5;++j)a[i][j]=b[i][j]; for(R int i=1;i<=10;++i)bul[i]=mp[i]; } } } int main(){ scanf("%d",&n); for(R int i=1;i<=5;++i) for(R int j=7;j>=0;--j){ scanf("%d",&a[j][i]); if(!a[j][i])break; bul[a[j][i]]++; } dfs(1); cout<<-1; return 0; }