HDU 4090 GemAnd Prince (DFS+BFS)/(DFS+DFS)

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4090


题意:相信大家都玩过消消看,连在一起大于等于3个相同的颜色就可以消去了,这道题目还加了另外的一个条件,每次消完了之后都会下落然后左移,问你最多能得多少分。

题解:开始的时候我的第一想法是BFS+DFS,然后果、果断MLE,最后看了别人的代码,基本上是DFS+DFS或者DFS+BFS,哎,为什么我的思维就是与众不同呢


先来个错误代码

BFS+DFS:(开大了MLE,开小了WA)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;

typedef long long LL;
const int N=2005;
const int M=555555;
const LL II=100000000;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);

int n,m,k;
int Max;
int cnt;
bool vis[10][10];
int t[8][2]={-1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1};
int xiao[10][10];
int leixing;
struct xh
{
    int value;
    short int s[8][8];
}w,e,q[M];

void prin()
{
    cout<<"************"<<endl;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
            cout<<w.s[i][j]<<" ";
        cout<<endl;
    }
    cout<<"************"<<endl;
}

void dfs(int i,int j)
{
    for(int k=0;k<8;k++)
    {
        int x=i+t[k][0];
        int y=j+t[k][1];
        if(x<0||x>=n||y<0||y>=m)    continue;
        if(vis[x][y]||w.s[x][y]!=leixing)   continue;
        vis[x][y]=1;
        w.s[x][y]=0;
        cnt++;
        dfs(x,y);
    }
}

void yidong()
{
    int i,j;
    for(i=0;i<m;i++)
    {
        int k=n-1;
        for(j=n-1;j>=0;j--)
        {
            if(w.s[j][i]!=0)
            {
                w.s[k][i]=w.s[j][i];
                if(k!=j)  w.s[j][i]=0;
                k--;
            }
        }
    }
    int k=0;
    for(j=0;j<m;j++)
    {
        if(w.s[n-1][j]!=0)
        {
            if(j!=k)
            {
                for(i=0;i<n;i++)
                    w.s[i][k]=w.s[i][j],w.s[i][j]=0;
            }

            k++;
        }
    }
}

void prine()
{
    cout<<"************"<<endl;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
            cout<<e.s[i][j]<<" ";
        cout<<endl;
    }
    cout<<"************"<<endl;
}

int maxscore()
{
    int sum=0,i,j;
    int ll[8]={0};
    for(i=0;i<n;i++)
        for(j=0;j<m;j++)
            ll[e.s[i][j]]++;
    for(i=1;i<=k;i++)
        if(ll[i]>=3)
            sum+=ll[i]*ll[i];
    return sum;
}

void BFS()
{
    int he=0,ta=0;
    int i,j;
    w.value=0;
    q[ta++]=w;
    while(he!=ta)
    {
        e=q[he++];
        if(he==M)
            he=0;
        if((maxscore()+e.value)<=Max)
            continue;
        memset(vis,0,sizeof(vis));
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                w=e;
                if(vis[i][j]||w.s[i][j]==0)   continue;
                leixing=w.s[i][j];
                w.s[i][j]=0;
                vis[i][j]=1;
                cnt=1;
                dfs(i,j);
                if(cnt<3)   continue;
                //prin();
                yidong();//prin(); system("pause");
                w.value+=cnt*cnt;
                if(Max<w.value)
                    Max=w.value;
                q[ta++]=w;
                if(ta==M)
                    ta=0;
            }
        }
    }

}

int main()
{
    while(~scanf("%d%d%d",&n,&m,&k))
    {
        int i,j;
        for(i=0;i<n;i++)
            for(j=0;j<m;j++)
                scanf("%d",&w.s[i][j]);
        Max=0;
        BFS();
        cout<<Max<<endl;
    }
    return 0;
}


AC代码:(DFS+DFS)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;

typedef long long LL;
const int N=2005;
const int M=555555;
const LL II=100000000;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);

int n,m,k;
int Max,cnt;
int w[8][8];
int t[8][2]={-1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1};
int leixing;

inline int maxscore()
{
    int sum=0,i,j;
    int ll[8];
    memset(ll,0,sizeof(ll));
    for(i=0;i<n;i++)
        for(j=0;j<m;j++)
            ll[w[i][j]]++;
    for(i=1;i<=k;i++)
        if(ll[i]>=3)
            sum+=ll[i]*ll[i];
    return sum;
}

inline void yidong()
{
    int i,j;
    for(i=0;i<m;i++)
    {
        int k=n-1;
        for(j=n-1;j>=0;j--)
        {
            if(w[j][i]!=0)
            {
                w[k][i]=w[j][i];
                if(k!=j)  w[j][i]=0;
                k--;
            }
        }
    }
    int k=0;
    for(j=0;j<m;j++)
    {
        if(w[n-1][j]!=0)
        {
            if(j!=k)
            {
                for(i=0;i<n;i++)
                    w[i][k]=w[i][j],w[i][j]=0;
            }

            k++;
        }
    }
}

void dfs(int i,int j,bool vis[][8])
{
    for(int k=0;k<8;k++)
    {
        int x=i+t[k][0];
        int y=j+t[k][1];
        if(x<0||x>=n||y<0||y>=m)    continue;
        if(vis[x][y]||w[x][y]!=leixing)   continue;
        vis[x][y]=1;
        w[x][y]=0;
        cnt++;
        dfs(x,y,vis);
    }
}

inline void debug(int p[][8])
{
    cout<<"************"<<endl;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
            cout<<p[i][j]<<" ";
        cout<<endl;
    }
    cout<<"************"<<endl;
}

inline void save(int sa[][8])
{
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            sa[i][j]=w[i][j];
}

inline void read(int sa[][8])
{
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            w[i][j]=sa[i][j];
}

void DFS(int value)
{
    if((maxscore()+value)<=Max)//剪枝
        return ;
    bool vis[8][8];
    memset(vis,0,sizeof(vis));
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            if(w[i][j]==0)
                vis[i][j]=1;
            if(vis[i][j])   continue;

            int sa[8][8];
            save(sa);//保存

            leixing=w[i][j];
            w[i][j]=0;
            cnt=1;  vis[i][j]=1;
            dfs(i,j,vis);
            if(cnt<3)  {read(sa);    continue;}

            yidong();

            int tempv=value+cnt*cnt;
            if(tempv>Max)   Max=tempv;
            DFS(tempv);
            read(sa);//读取
        }
    }
}

int main()
{
    while(~scanf("%d%d%d",&n,&m,&k))
    {
        int i,j;
        for(i=0;i<n;i++)
            for(j=0;j<m;j++)
                scanf("%d",&w[i][j]);
        Max=0;
        DFS(0);
        cout<<Max<<endl;
    }
    return 0;
}
/*
2 2 2
1 1
1 2

3 3 3
1 1 3
1 2 1
1 1 2

5 4 3
2 2 3 3
1 1 3 3
3 2 2 2
3 1 1 1
3 1 2 2
*/


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值