Mayan游戏
总而言之,四条剪枝原则:
(1)交换两个颜色相同的块没有意义
(2)一个块的左边是非空块时不需要考虑左移,因为会和之前的块右移重复,即只有当左块为空时才左移
(3)根据题目优先度的排序,可以知道,右移优先于左移,所以在dfs时先考虑右移
(4)如果有一种颜色当前的块数目x满足1<=x<=2,则此情况不合法
#include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; bool vis[10][10]; bool flag[11]; int map[10][10]; int step[10][5]; int count[11]; int n,N; int del( ) { memset( vis,1,sizeof vis ); int res=0; int l,r,u,d,x,y,t; bool cs=0; for(int i=1;i<=5;i++) for(int j=1;j<=7;j++) if( map[ i ][ j ] ) if( ( j>=2 && map[ i ][ j-1 ] ) || j==1 ) { l=r=i; u=d=j; while( l>=2 && map[ l-1 ][ j ]==map[ i ][ j ] ) l--; while(r<4 && map[ r+1 ][ j ]==map[ i ][ j ] ) r++; while( d>=2 && map[ i ][ d-1 ]==map[ i ][ j ] ) d--; while( u<=6 && map[ i ][ u+1 ]==map[ i ][ j ] ) u++; if( r-l>=2 ) for(int k=l;k<=r;k++) vis[ k ][ j ]=0; if( u-d>=2 ) for(int k=d;k<=u;k++) vis[ i ][ k ]=0; } for(int i=1;i<=5;i++) for(int j=1;j<=7;j++) if( !vis[ i ][ j ] ) { res++; map[ i ][ j ]=0; } for(int i=1,j;i<=5;i++) { for(j=1;j<=7;j++) if( !map[ i ][ j ] ) break; x=j; for( ;j<=7;j++ ) if( map[ i ][ j ] ) break; if( j==8 ) continue; y=j-1; t=0; for( j=x;j<=7;j++ ) { t++; if( !map[ i ][ y+t ] || map[ i ][ j ]) break; map[ i ][ j ]=map[ i ][ y+t ]; map[ i ][ y+t ]=0; cs=1; } } if( cs ) res+=del( ); return res; } bool judge( ) { memset( count,0x0,sizeof count ); for(int i=1;i<=5;i++) for(int j=1;j<=7;j++) count[ map[ i ][ j ] ]++; for(int i=1;i<=N;i++) if( count[ i ]>=1 && count[ i ]<=2 ) return 0; return 1; } void dfs(int num,int tot) { if( !judge( ) ) return ; if( num>=n+1 ) { if( !tot ) { cout<<"搜索次数 : "<<zzl<<endl; for(int i=1;i<=n;i++) printf("%d %d %d\n",step[ i ][ 1 ]-1,step[ i ][ 2 ]-1,step[ i ][ 3 ] ); exit(0); } return ; } int x,y; int temp[10][10],p,q; bool cs; for(int i=1;i<=5;i++) for(int j=1;j<=7;j++) temp[ i ][ j ]=map[ i ][ j ]; for(int i=1;i<=5;i++) for(int j=1;j<=7;j++) { if( map[ i ][ j ] ) { cs=1; if( i<=4 &&map[ i ][ j ]!=map[ i+1 ][ j ] ) { swap( map[ i ][ j ],map[ i+1 ][ j ] ); step[ num ][ 1 ]=i; step[ num ][ 2 ]=j; step[ num ][ 3 ]=1; p=tot-del(); dfs( num+1,p ); cs=0; } if( !cs ) { cs=1; for(p=1;p<=5;p++) for(q=1;q<=7;q++) map[ p ][ q ]=temp[ p ][ q ]; } if( i>=2 && !map[ i-1 ][ j ] ) { swap( map[ i ][ j ],map[ i-1 ][ j ] ); step[ num ][ 1 ]=i; step[ num ][ 2 ]=j; step[ num ][ 3 ]=-1; p=tot-del(); dfs( num+1,p ); cs=0; } if( !cs ) for(p=1;p<=5;p++) for(q=1;q<=7;q++) map[ p ][ q ]=temp[ p ][ q ]; } } } int main() { int x,y=0; scanf("%d",&n); for(int i=1,j;i<=5;i++) { j=0; scanf("%d",&x); while( x ) { map[ i ][ ++j ]=x; if( !flag[ x ] ) { flag[ x ]=1; N++; } y++; scanf("%d",&x); } } dfs( 1,y ); cout<<-1<<endl; return 0; }