题目链接:点此进入
思路:
先bfs查找块(能一次消除的),然后对这些块dfs,然后模拟下降操作和左移操作就够了。
剪枝:
当前分+当前的相同的全消除得的分<=ans就不用搜了。
注意:
数组传递,传递的是指针,如果修改值则修改的是实际值。
感想:
这题其实说起来也还不算很难的那种,因为至少知道应该怎么搜,所以不要怕它。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define maxn 10 using namespace std; int n,m,k,ans,sx,sy; int mp[maxn][maxn]; int dx[]= {-1,1,0,0,-1,-1,1,1}; int dy[]= {0,0,-1,1,-1,1,-1,1}; struct Node { int cnt; int x[70],y[70]; } tk[30]; struct node { int x,y; } cur,now,q[70]; bool bfs(int tt[][10],int cxx) { int i,j,nx,ny,tx,ty,xxc,color; int head=0,tail=-1; cur.x=sx; cur.y=sy; color=tt[sx][sy]; tt[sx][sy]=0; xxc=0; q[++tail]=cur; while(head<=tail) { now=q[head]; head++; nx=now.x; ny=now.y; xxc++; tk[cxx].x[xxc]=nx; tk[cxx].y[xxc]=ny; for(i=0; i<8; i++) { tx=nx+dx[i]; ty=ny+dy[i]; if(tx<1||tx>n||ty<1||ty>m||tt[tx][ty]!=color) continue ; cur.x=tx; cur.y=ty; tt[tx][ty]=0; q[++tail]=cur; } } tk[cxx].cnt=xxc; if(xxc>=3) return true ; return false ; } int solve(int tt[][10]) //找块 { int i,j,cxx=0; for(i=1; i<=n; i++) { for(j=1; j<=m; j++) { if(tt[i][j]) { sx=i,sy=j; cxx++; if(!bfs(tt,cxx)) cxx--; } } } return cxx; } int change(int tt[][10],Node link) { int i,j,k,sz,val,cc,cxx; int c[10]= {0}; int cou[7]={0}; int pos[10]; sz=link.cnt; for(i=1; i<=sz; i++) { tt[link.x[i]][link.y[i]]=0; } for(i=1;i<=m;i++) { pos[i]=n; } for(i=n;i>=1;i--) // 模拟下降操作 { for(j=1;j<=m;j++) { if(tt[i][j]) { tt[pos[j]][j]=tt[i][j]; if(pos[j]!=i) tt[i][j]=0; pos[j]--; } } } cc=1; for(j=1;j<=m;j++) // 模拟左移操作 { cxx=0; for(i=1;i<=n;i++) { if(tt[i][j]) cxx++; } if(cxx) { for(i=1;i<=n;i++) { tt[i][cc]=tt[i][j]; if(j!=cc) tt[i][j]=0; cou[tt[i][cc]]++; } cc++; } } val=0; for(i=1;i<=6;i++) { val+=cou[i]*cou[i]; } return val; } void dfs(int tmp[][10],int score) { if(ans<score) ans=score; int i,j,num,val,maval; int tt[maxn][maxn]; Node link[30]; memcpy(tt,tmp,sizeof(tt)); num=solve(tt); memcpy(link,tk,sizeof(link)); for(i=1; i<=num; i++) { memcpy(tt,tmp,sizeof(tt)); maval=change(tt,link[i]); val=link[i].cnt*link[i].cnt; if(score+val+maval>ans) dfs(tt,score+val); } } int main() { int i,j; while(~scanf("%d%d%d",&n,&m,&k)) { memset(mp,0,sizeof(mp)); for(i=1; i<=n; i++) { for(j=1; j<=m; j++) { scanf("%d",&mp[i][j]); } } ans=0; dfs(mp,0); printf("%d\n",ans); } return 0; }