noip2011 Mayan游戏 dfs+模拟

3 篇文章 0 订阅
3 篇文章 0 订阅

代码能力太弱啊,调了一天。首先我bfs挂了,因为状态太多而MLE,好像只能dfs,然后bfs改dfs过程中傻x错误一大堆。这道题主要是模拟比较麻烦,消除块的情况非常复杂。剪枝的话,如果一个块左边有块,就不用搜它向左移的情况,因为左边的块向右移会更优。剪这一个应该就可以。还有总结这几天做题经验,一定谨慎使用STL,删块的时候把要删的坐标加入队列最后一起删,结果用了8s,记录了一下删块,结果不到1s。开始没有意识到这个问题,一天就这样过去了。%%%当场A掉的大神。最后希望大家打代码要有耐心,调个大爆搜还是挺涨姿势的。

#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
int n;
struct M{
    int x[6],y[6],z[6];
    int mp[9][7];
    int col[12],c;
    int check()
    {
        int h=1;
        for(int i=1;i<=c;i++)
            if(col[i]){h=0;if(col[i]<3)return 2;}
        return h;
    }
    void ans()
    {
        for(int i=0;i<n;i++)
            printf("%d %d %d\n",x[i]-1,7-y[i],z[i]);
    }
    void print()
    {
        for(int i=1;i<=7;i++)
        {
            for(int j=1;j<=5;j++)
                cout<<mp[i][j];
            puts("");
        }
    }
    bool fall()
    {
        bool h=0;
        for(int i=6;i>=1;i--)
        for(int j=1;j<=5;j++)
        {
            if(!mp[i][j]) continue;
            int x=i;
            while(!mp[x+1][j])
                {x++;h=1;}
            swap(mp[i][j],mp[x][j]);
        }
        return h;
    }
    void del()
    {
        for(int j=1;j<=7;j++)
        for(int i=1;i<=5;i++)
        {
            int p=mp[j][i];
            if(p&&p==mp[j][i+1]&&p==mp[j][i+2])
            {
                col[p]-=3;
                mp[j][i]=0;
                mp[j][i+1]=0;
                mp[j][i+2]=0;
                for(int x=0;x<=2;x++)
                {
                    int r1=1,r2=1;
                    while(mp[j-r1][i+x]==p) r1++;
                    while(mp[j+r2][i+x]==p) r2++;
                    if(r1+r2-1>=3)
                    {
                        for(int w=j-r1+1;w<=j+r2-1;w++)
                        {
                            col[mp[w][i+x]]--;
                            mp[w][i+x]=0;
                        }
                    }
                }
                for(int x=3;x<=4;x++)
                {
                    if(p==mp[j][i+x])
                    {
                        col[mp[j][i+x]]--;
                        mp[j][i+x]=0;
                        int r1=1,r2=1;
                        while(mp[j-r1][i+x]==p) r1++;
                        while(mp[j+r2][i+x]==p) r2++;
                        if(r1+r2-1>=3)
                        {
                            for(int w=j-r1+1;w<=j+r2-1;w++)
                            {
                                col[mp[w][i+x]]--;
                                mp[w][i+x]=0;
                            }
                        }
                    }
                    else break;
                }
            }
            else if(p&&p==mp[j+1][i]&&p==mp[j+2][i])
            {
                col[p]-=3;
                mp[j][i]=0;
                mp[j+1][i]=0;
                mp[j+2][i]=0;
                for(int x=1;x<=2;x++)
                {
                    int r1=1,r2=1;
                    while(mp[j+x][i-r1]==p) r1++;
                    while(mp[j+x][i+r2]==p) r2++;
                    if(r1+r2-1>=3)
                    {
                        for(int w=i-r1+1;w<=i+r2-1;w++)
                        {
                            col[mp[j+x][w]]--;
                            mp[j+x][w]=0;
                        }
                    }
                }
                for(int x=3;x<=4;x++)
                {
                    if(p==mp[j+x][i])
                    {
                        col[mp[j+x][i]]--;
                        mp[j+x][i]=0;
                        int r1=1,r2=1;
                        while(mp[j+x][i-r1]==p) r1++;
                        while(mp[j+x][i+r2]==p) r2++;
                        if(r1+r2-1>=3)
                        {
                            for(int w=i-r1+1;w<=i+r2-1;w++)
                            {
                                col[mp[j+x][w]]--;
                                mp[j+x][w]=0;
                            }
                        }
                    }
                    else break;
                }
            }
        }
        if(fall())
            del();
    }
};
M A;int ans;
void dfs(int X)
{
    if(ans) return;
    int p=A.check();
    if(p==1&&X==n){ans=1;A.ans();return;}
    if(p==2) return;
    if(X==n)return;
    for(int i=1;i<=5;i++)
    for(int j=7;j>=1;j--)
    {
        if(!A.mp[j][i]) break;
        M B=A;
        if(i<5)
        {
            A.x[X]=i;A.y[X]=j;
            A.z[X]=1;
            swap(A.mp[j][i],A.mp[j][i+1]);
            A.fall();A.del();
            dfs(X+1);A=B;
        }
        if(i>1&&!A.mp[j][i-1])
        {

            A.x[X]=i;A.y[X]=j;
            A.z[X]=-1;
            swap(A.mp[j][i],A.mp[j][i-1]);
            A.fall();A.del();
            dfs(X+1);A=B;
        }
    }
}
int main()
{   int x;
    scanf("%d",&n);
    for(int i=1;i<=5;i++)
    {
        int tot=0;
        while(true)
        {
            scanf("%d",&x);
            A.mp[7-tot][i]=x;
            A.c=max(A.c,x);
            if(!x)break;
            A.col[x]++;
            tot++;
        }
    }
    for(int i=1;i<=5;i++)
        A.mp[8][i]=23+i;
    for(int i=1;i<=7;i++)
        A.mp[i][6]=233+i;
    dfs(0);
    if(!ans) puts("-1");
    return 0;
}

从昨天下午就开始做这道题,晚上还是没有做出来,GG,心情很不爽,去楼下物理搞事情,简直interesting。其实一个人或一群人全身心投入去钻研一个东西,真的是很愉♂快的(羡慕隔壁物理的老司机们)。

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值