题意:
消消乐,给定一个n*m的多个颜色的砖块矩阵,你可以选择相连的相同颜色的砖块数目大于等于3个的消去,每次消去x个砖块得到的分数是x*x,每次消去后矩阵会变化,上面的浮空的砖块会掉下来,右边的隔开的砖块会整体向左靠,详细变化方式见题目给的说明,现在问你能得到的最大分数。
思路:
题目第一感觉就是一道不那么好写的搜索,仔细分析了一下好像也没有其他做法,写的时候注意下消去后的新矩阵的变化,加上常用的优化,若当前矩阵能得到的最大值小于已经有的最大答案,就停止继续遍历。
代码:
#include<bits/stdc++.h>
const int X[8]={-1,-1,-1,0,0,1,1,1};
const int Y[8]={-1,0,1,-1,1,-1,0,1};
using namespace std;
int n,m,k,ans;
struct node{
int A[8][8];
};
struct point{
int x,y,num;
point(){};
point(int _x,int _y,int _num=0){
x = _x;y = _y; num = _num;
}
};
bool vis[8][8];
int get(node &tt,int x,int y,int k){
vis[x][y]=true;
queue<point>Q;
int res = 1;
Q.push(point(x,y));
while(!Q.empty()){
point t = Q.front();
Q.pop();
for(int i=0,a,b;i<8;i++){
a = t.x+X[i];
b = t.y+Y[i];
if(a>=0&&a<n&&b>=0&&b<m&&tt.A[a][b]==tt.A[x][y]&&!vis[a][b]){
vis[a][b]=true;
tt.A[a][b]=k;
Q.push(point(a,b));
res++;
}
}
}
tt.A[x][y]=k;
return res;
}
void oper(node &M){
for(int j=0;j<m;j++){
for(int s=n-2,e=n-1;e&&s>=0;e--){
if(!M.A[e][j]){s = min(s,e-1);
while(s>=0&&!M.A[s][j])s--;
if(s>=0){
M.A[e][j]=M.A[s][j];
M.A[s][j]=0;
}
}
}
}
for(int j=0,jj=0;j<m-1;j++){
if(!M.A[n-1][j]){
jj = max(jj,j+1);
while(jj<m&&!M.A[n-1][jj])jj++;
if(jj<m){
for(int i=0;i<n;i++){
M.A[i][j]=M.A[i][jj];
M.A[i][jj]=0;
}
}
}
}
}
int num[10];
bool check(node& M,int sum){
memset(num,0,sizeof(num));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
num[M.A[i][j]]++;
}
}
for(int i=1;i<=k;i++){
if(num[i]>2)sum+=num[i]*num[i];
}return sum<=ans;
}
void dfs(node &M,int sum=0){
ans = max(sum,ans);
if(check(M,sum))return ;
queue<point>Q;
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(M.A[i][j]&&!vis[i][j]){
int cnt = get(M,i,j,M.A[i][j]);
if(cnt>=3)Q.push(point(i,j,cnt));
}
}
}
while(!Q.empty()){memset(vis,0,sizeof(vis));
point t = Q.front();Q.pop();
if(t.num<3)continue;
node nx = M;
int cnt = get(nx,t.x,t.y,0);
oper(nx);
dfs(nx,sum+cnt*cnt);
}
}
int main(){
while(scanf("%d%d%d",&n,&m,&k)==3){
node t;ans = 0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%d",&t.A[i][j]);
}
}
dfs(t);
printf("%d\n",ans);
}return 0;
}