P1312 Mayan游戏

传送门:https://www.luogu.org/problemnew/show/P1312

辣鸡模拟题!就是暴力乱搞,然后一堆小细节要注意qwq

把某谷的数据点骗完了终于过了呕

然后是剪枝的四个原则:(转载)

(1)交换两个颜色相同的块没有意义

(2)一个块的左边是非空块时不需要考虑左移,因为会和之前的块右移重复,即只有当左块为空时才左移

(3)根据题目优先度的排序,可以知道,右移优先于左移,所以在dfs时先考虑右移

(4)如果有一种颜色当前的块数目x满足1<=x<=2,则此情况不合法

然后细心打一下就好啦....

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <ctime>
#define maxn 15
using namespace std;

bool flag,tag[maxn][maxn];
int n,a[maxn][maxn],cnt[maxn+5],ans[maxn][3];

int read()
{
    int xx=0,kk=1;char ch=' ';
    while(!isdigit(ch)){ch=getchar();if(ch=='-')kk=-1;}
    while(isdigit(ch)){xx=xx*10+ch-'0';ch=getchar();}
    return kk*xx;
}

bool find()
{
    bool flag=false;
    memset(tag,false,sizeof(tag));
    for(int i=1;i<=5;++i)
    for(int j=1;j<=7;++j)
    {
        if(!a[i][j]) continue;
        if(a[i][j]==a[i-1][j]&&a[i][j]==a[i+1][j])
            tag[i][j]=tag[i-1][j]=tag[i+1][j]=true,flag=true;
        if(a[i][j]==a[i][j-1]&&a[i][j]==a[i][j+1])
            tag[i][j]=tag[i][j-1]=tag[i][j+1]=true,flag=true;
    }
    return flag;	
}

void del()
{
    for(int i=1;i<=5;++i)
    {
        int low=0,sum=0;
        for(int j=1;j<=7;++j)
        {
            if(!low&&tag[i][j]) low=j;
            if(tag[i][j]) sum++;
        }
        for(int j=1;j<=7;++j)
            if(j>=low) a[i][j]=a[i][j+sum];
    }
}

bool success()
{
    for(int i=1;i<=5;++i)
    for(int j=1;j<=7;++j)
        if(a[i][j]) return false;
    return true;
}

bool check()
{
    memset(cnt,0,sizeof(cnt));
    for(int i=1;i<=5;++i)
    for(int j=1;j<=7;++j)
        if(a[i][j]) cnt[a[i][j]]++;
    for(int i=1;i<=10;++i)
        if(cnt[i]&&cnt[i]<3) return false;
    return true;
}

bool dfs(int x,int y,int dep,int dir)
{
    if(dep<0||x+dir<1||x+dir>5) return false;
    if(a[x+dir][y]==a[x][y]) return false;
    if(dir==-1&&a[x+dir][y]) return false;
    if(!check()) return false;
    int tmp[maxn][maxn],len=0;
    while(!a[x+dir][y-len]&&len<y) len++;
    if(len)
    {	
        swap(a[x][y],a[x+dir][y-len+1]);
        for(int i=y;i<=7;++i) a[x][i]=a[x][i+1];
    } 
    else swap(a[x][y],a[x+dir][y]);
    while(find()) del();
    memcpy(tmp,a,sizeof(tmp));
    if(success())
    {	
        flag=true;
        ans[dep][0]=x,ans[dep][1]=y,ans[dep][2]=dir;
        return true;
    } 
    for(int i=1;i<=5;++i)
    for(int j=1;j<=7;++j)
    {
        if(!a[i][j]) continue;
        memcpy(a,tmp,sizeof(a));
        if(dfs(i,j,dep-1,1)) 
        {
            ans[dep][0]=x,ans[dep][1]=y,ans[dep][2]=dir;
            return true;
        }
        memcpy(a,tmp,sizeof(a));
        if(dfs(i,j,dep-1,-1))
        {
            ans[dep][0]=x,ans[dep][1]=y,ans[dep][2]=dir;
            return true;
        }
		memcpy(a,tmp,sizeof(a));
    }
    return false;
}

int main()
{
    n=read();
    int tmp[maxn][maxn];
    for(int i=1;i<=5;++i)
    for(int j=1;j<=8;++j)
    {
        a[i][j]=read();
        if(!a[i][j]) break;
    }
    memcpy(tmp,a,sizeof(a));
    for(int i=1;i<=5;++i)
    for(int j=1;j<=7;++j)
    {
        if(!a[i][j]) continue;
        memcpy(a,tmp,sizeof(tmp));
        if(dfs(i,j,n-1,1)) break;
        memcpy(a,tmp,sizeof(tmp));
        if(dfs(i,j,n-1,-1)) break;
    }
    if(flag)
    {
        for(int i=n-1;i>=0;--i)
         if(ans[i][0]&&ans[i][1]) printf("%d %d %d\n",ans[i][0]-1,ans[i][1]-1,ans[i][2]);
    }
    else puts("-1");
    return 0;	
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值