zoukankan      html  css  js  c++  java
  • hdu 4090 GemAnd Prince

    题目大意:

    别人说是消消看,至于你玩没玩过。反正我是没玩过的。

    就是选择一个钻石,可以消除与它相连的所有钻石。并获得 消除数量*消除数量  的分

    思路:

    直接暴搜,然后用一个cnt数组表示每一种钻石剩余的数量,进行剪枝。


    被坑了两天。 开始用BFS 搜,用DFS进行标记。超内存。

    后来改成了  DFS + DFS 发现有些细节不好处理。

    最后换成了DFS搜  BFS标记消除。



    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    int dx[] = {0,0,1,-1,1,1,-1,-1};
    int dy[] = {1,-1,0,0,1,-1,-1,1};
    
    int n,m,k;
    int map[9][9];
    
    int save[9][9][70];
    bool vis[9][9][70];
    int cnt[7];
    int ans;
    
    struct node
    {
        int posx,posy;
    }Q[1000];
    bool ok(int x,int y)
    {
        if(x>=1 && x<=n && y>=1 && y<=m)return true;
        return false;
    }
    void mtos(int dep)//存地图
    {
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        save[i][j][dep]=map[i][j];
    }
    void stom(int dep)
    {
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        map[i][j]=save[i][j][dep];
    }
    
    void reset(int top)//重新摆放
    {
        for(int i=0;i<top;i++)//与后面的BFS 对应  消除。
        map[Q[i].posx][Q[i].posy]=0;
    
        int tmp[9][9];
    
        int ii,jj;
        for(int j=1;j<=m;j++)
        {
            ii=n;
            for(int i=n;i>=1;i--)
            {
                if(map[i][j]!=0)
                {
                    jj=j;
                    tmp[ii--][jj]=map[i][j];
                }
            }
            while(ii>=1)
            {
                tmp[ii][j]=0;
                ii--;
            }
        }
    
        int move[9],ccnt=0;
        memset(move,0,sizeof(move));
    
        for(int j=1;j<=m;j++)
        {
            if(tmp[n][j]==0)
            {
                move[j]=0;
                ccnt++;
                continue;
            }
            move[j]=ccnt;
        }
        for(int j=1;j<=m;j++)
        {
            for(int i=1;i<=n;i++)
            {
                tmp[i][j-move[j]]=tmp[i][j];
                if(move[j])tmp[i][j]=0;
            }
        }
    
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        map[i][j]=tmp[i][j];
    }
    inline int h()//估价函数  剪枝
    {
        int sum=0;
    
        for(int i=1;i<=k;i++)
        if(cnt[i]>=3)sum+=(cnt[i]*cnt[i]);
    
        return sum;
    }
    
    int mark(int x,int y,int val,int dep)//进行标记
    {
        int head=0,tail=0;
        node w,e;
    
        Q[tail].posx=x;
        Q[tail++].posy=y;
        vis[x][y][dep]=true;
        while(head<tail)
        {
            w=Q[head];
            head++;
            for(int i=0;i<8;i++)
            {
                e=w;
                int xx=e.posx+dx[i];
                int yy=e.posy+dy[i];
    
                if(ok(xx,yy) && !vis[xx][yy][dep] && map[xx][yy]==val)
                {
                    vis[xx][yy][dep]=true;
                    e.posx=xx;
                    e.posy=yy;
                    Q[tail++]=e;
                }
            }
        }
        return tail;
    }
    
    void dfs(int tans,int dep)
    {
        ans=max(ans,tans);
        if(h()+tans<=ans)return;
    
        for(int i=1;i<=n;i++)//这里不可少  没进入一次新的DFS  都要重置
        for(int j=1;j<=m;j++)
        vis[i][j][dep]=false;
    
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(map[i][j]!=0 && !vis[i][j][dep])
                {
                    int tscore=mark(i,j,map[i][j],dep);
    
                    if(tscore>=3)
                    {
                        mtos(dep);
                        int vv=map[i][j];//被这里坑了好久  RESET之后地图就会变了。无力吐槽自己
                        cnt[vv]-=tscore;
                        reset(tscore);
                        dfs(tans+tscore*tscore,dep+1);
                        cnt[vv]+=tscore;
                        stom(dep);
                    }
                }
            }
        }
    }
    
    int main()
    {
        while(scanf("%d%d%d",&n,&m,&k)!=EOF)
        {
            memset(cnt,0,sizeof(cnt));
    
            for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&map[i][j]);
                cnt[map[i][j]]++;
            }
            ans=0;
            memset(vis,false,sizeof(vis));
    
            dfs(0,1);
            printf("%d
    ",ans);
        }
        return 0;
    }
    
    /*
    8 8 6
    1 1 1 2 2 2 3 3
    4 4 1 1 4 4 4 4
    5 5 5 6 6 6 6 1
    2 2 2 2 4 4 4 3
    1 4 5 6 3 3 2 1
    4 4 4 5 5 5 5 6
    5 5 5 5 5 3 3 3
    5 5 2 2 2 1 3 1
    */
    


    这里在给出DFS + DFS 的 AC代码。 效率没有上一个快,只是为了检验自己之前的错误。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    int dx[] = {0,0,1,-1,1,1,-1,-1};
    int dy[] = {1,-1,0,0,1,-1,-1,1};
    int n,m,k;
    int map[9][9];
    
    int save[9][9][70];
    bool vis[9][9][70];
    int cnt[7];
    int tscore;
    int ans;
    
    void debugcnt()
    {
        for(int i=1;i<=k;i++)
        printf("%d ",cnt[i]);
    
        puts("");
        system("pause");
       // getchar();
    }
    bool ok(int x,int y)
    {
        if(x>=1 && x<=n && y>=1 && y<=m)return true;
        return false;
    }
    void debug()
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                printf("%d",map[i][j]);
            }
            puts("");
        }
        puts("");
        //getchar();
    }
    void mtos(int dep)
    {
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            save[i][j][dep]=map[i][j];
        }
    }
    void stom(int dep)
    {
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            map[i][j]=save[i][j][dep];
        }
    }
    void reset()
    {
        int tmp[9][9];
    
        int ii,jj;
        for(int j=1;j<=m;j++)
        {
            ii=n;
            for(int i=n;i>=1;i--)
            {
                if(map[i][j]!=0)
                {
                    jj=j;
                    tmp[ii--][jj]=map[i][j];
                }
            }
            while(ii>=1)
            {
                tmp[ii][j]=0;
                ii--;
            }
        }
    
        int move[9],ccnt=0;
        memset(move,0,sizeof(move));
    
        for(int j=1;j<=m;j++)
        {
            if(tmp[n][j]==0)
            {
                move[j]=0;
                ccnt++;
                continue;
            }
            move[j]=ccnt;
        }
        for(int j=1;j<=m;j++)
        {
            for(int i=1;i<=n;i++)
            {
                tmp[i][j-move[j]]=tmp[i][j];
                if(move[j])tmp[i][j]=0;
            }
        }
    
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        map[i][j]=tmp[i][j];
    }
    int h()
    {
        int sum=0;
        for(int i=1;i<=k;i++)
        if(cnt[i]>=3)sum+=cnt[i]*cnt[i];
        return sum;
    }
    
    void mark(int x,int y,int val,int dep)
    {
        for(int i=0;i<8;i++)
        {
            int xx=dx[i]+x;
            int yy=dy[i]+y;
            if(ok(xx,yy) && !vis[xx][yy][dep] && map[xx][yy]==val)
            {
                vis[xx][yy][dep]=true;
                map[xx][yy]=0;
                tscore++;
                mark(xx,yy,val,dep);
            }
        }
    }
    
    void dfs(int tans,int dep)
    {
        if(tans+h()<=ans){return;}
        ans=max(ans,tans);
    
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        vis[i][j][dep]=false;
    
    
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(map[i][j]!=0 && !vis[i][j][dep])
                {
                    mtos(dep);
                    int tt;
                    tscore=0;
                    int vv=map[i][j];
                   
                    mark(i,j,map[i][j],dep);
                    tt=tscore;
                    if(tt<3){stom(dep);continue;}
                    cnt[vv]-=tt;
                    reset();
                    dfs(tans+tt*tt,dep+1);
                    cnt[vv]+=tt;
                    stom(dep);
                }
            }
        }
    }
    
    int main()
    {
        while(scanf("%d%d%d",&n,&m,&k)!=EOF)
        {
            memset(cnt,0,sizeof(cnt));
    
            for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&map[i][j]);
                cnt[map[i][j]]++;
            }
            ans=0;
            dfs(0,1);
    
            printf("%d
    ",ans);
        }
        return 0;
    }
    


    再上一份自己之前超内存的BFS 的代码。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    
    using namespace std;
    int dx[] = {0,0,-1,1,1,1,-1,-1};
    int dy[] = {1,-1,0,0,1,-1,1,-1};
    int n,m,k;
    struct node
    {
        short map[9][9];
        int score;
    };
    
    bool vis[9][9];
    bool v[9][9];
    bool ok(int x,int y)
    {
        if(x<=n && x>=1 && y>=1 && y<=m)return true;
        return false;
    }
    int tscore;
    
    void dfs(int x,int y,node &t,int val)
    {
        for(int i=0;i<8;i++)
        {
            int xx=dx[i]+x;
            int yy=dy[i]+y;
            if( ok(xx,yy) && !vis[xx][yy] && t.map[xx][yy]==val)
            {
                vis[xx][yy]=true;
                t.map[xx][yy]=0;
                tscore++;
                v[xx][yy]=true;
                dfs(xx,yy,t,val);
            }
        }
    }
    int h(node t)
    {
        int tcnt[7];
    
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(t.map[i][j]!=0)
                {
                    tcnt[t.map[i][j]]++;
                }
            }
        }
        int sum=0;
        for(int i=1;i<=k;i++)
        if(tcnt[i]>=3)sum+=tcnt[i]*tcnt[i];
    
        return sum;
    }
    node reset(node t)
    {
        node tmp=t;
        int ii,jj;
        for(int j=1;j<=m;j++)
        {
            ii=n;
            for(int i=n;i>=1;i--)
            {
                if(t.map[i][j]!=0)
                {
                    jj=j;
                    tmp.map[ii--][jj]=t.map[i][j];
                }
            }
            while(ii>=1)
            {
                tmp.map[ii][j]=0;
                ii--;
            }
        }
        //debug(tmp);
    
        int move[9],ccnt=0;
        memset(move,0,sizeof(move));
    
        for(int j=1;j<=m;j++)
        {
            if(tmp.map[n][j]==0)
            {
                move[j]=0;
                ccnt++;
                continue;
            }
            move[j]=ccnt;
        }
        for(int j=1;j<=m;j++)
        {
            for(int i=1;i<=n;i++)
            {
                tmp.map[i][j-move[j]]=tmp.map[i][j];
                if(move[j])tmp.map[i][j]=0;
            }
        }
        return tmp;
    }
    int ans;
    void bfs(node t)
    {
        queue<node>Q;
    
        node w,e;
        Q.push(t);
    
        while(!Q.empty())
        {
            w=Q.front();
            Q.pop();
    
            if(w.score>ans)
            {
                ans=w.score;
            }
            memset(v,false,sizeof(v));
    
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    if(v[i][j])continue;
                    if(w.map[i][j]!=0)
                    {
                        e=w;
                        tscore=0;
                        memset(vis,false,sizeof(vis));
                        dfs(i,j,e,e.map[i][j]);
    
                        if(tscore>=3)
                        {
                            e=reset(e);
                            e.score+=(tscore*tscore);
                            if(e.score+h(e)<=ans)continue;
                            Q.push(e);
                        }
                    }
                }
            }
        }
    }
    int main()
    {
        while(scanf("%d%d%d",&n,&m,&k)!=EOF)
        {
            node t;
            for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&t.map[i][j]);
            }
    
            t.score=0;
            ans=0;
            bfs(t);
            printf("%d
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    css篇-less,scss 用calc问题
    工具篇-Mac上搭建本地svn服务器以及使用Cornerstone进行本地版本控制
    小程序篇-开发工具报错
    js篇-json字符串与json对象相互转化
    小程序篇- data 数据绑定
    RN-android 打包后,部分图片不显示
    asxios--form data提交,setcookie
    RN-系列
    纯css 实现横向滚动条--移动端
    Oralce给字段追加字符,以及oracle 给字段替换字符
  • 原文地址:https://www.cnblogs.com/pangblog/p/3293808.html
Copyright © 2011-2022 走看看