hdu 4090 GemAnd Prince (bfs+dfs+模拟)

题目链接:点此进入


思路:

先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;
}






你可能感兴趣的:(hdu 4090 GemAnd Prince (bfs+dfs+模拟))