1. 程式人生 > >P1312 Mayan遊戲

P1312 Mayan遊戲

辣雞模擬題!就是暴力亂搞,然後一堆小細節要注意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;	
}