社区讨论

90分求助。。差点就AC了

P1312[NOIP 2011 提高组] Mayan 游戏参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mi6greyd
此快照首次捕获于
2025/11/20 04:37
4 个月前
此快照最后确认于
2025/11/20 04:37
4 个月前
查看原帖
CPP
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>

using namespace std;

int n,a[5][7],t,j,s,cleared,block[11];

struct rst{
    int x,y,direct;
} stack[5];

bool dropOnce(int i,int j)        //被异步调用的掉落函数,每执行一次方块向下掉落一格
{                                //返回值 true:下方为空并已向下掉落一格,false:下方有方块
    if (a[i][j-1]!=0) return false;
    a[i][j-1] = a[i][j];
    a[i][j] = 0;
}

void drop()
{
    bool uncplt;
    for (int i = 0; i<5; i++)
    {
        uncplt = true;
        while (uncplt)
        {
            uncplt = false;
            for (int j = 1; j<7; j++)
                if (a[i][j]!=0&&dropOnce(i,j))
                    uncplt = true;
        }
    }
}

void print()
{
    for (int i = 5; i>=0; i--)
    {
        for (int j = 0; j<5; j++)
            cout<<a[j][i]<<' ';
        cout<<endl;
    }
    cout<<endl;
}

int clear()
{
    int top,bottom,left,right,clearNow = 0;
    bool canClear[5][7];
    memset(canClear,0,sizeof(canClear));
    
    drop();
    for (int i = 0; i<5; i++)
        for (int j = 0; j<7; j++)
        {
            if (a[i][j]==0||canClear[i][j]) continue;
            top = 0; bottom = 0; left = 0; right = 0;
            while (top<=5-j&&a[i][j+top+1]==a[i][j]) top++;
            while (bottom<=j-1&&a[i][j-bottom-1]==a[i][j]) bottom++;
            while (right<=3-i&&a[i+right+1][j]==a[i][j]) right++;
            while (left<=i-1&&a[i-left-1][j]==a[i][j]) left++;
            if (top>=2) for (; top>=0; top--) canClear[i][j+top] = true;
            if (bottom>=2) for (; bottom>=0; bottom--) canClear[i][j-bottom] = true;
            if (right>=2) for (; right>=0; right--) canClear[i+right][j] = true;
            if (left>=2) for (; left>=0; left--) canClear[i-left][j] = true;
        }
    for (int i = 0; i<5; i++)
        for (int j = 0; j<7; j++)
            if (canClear[i][j])
            {
                a[i][j] = 0;
                clearNow++;
                cleared++;
            }
    if (clearNow>0)
    {
        /*cout<<clearNow<<endl;
        for (int j = 0; j<n; j++)
            printf("%d %d %d\n", stack[j].x, stack[j].y, stack[j].direct);
        print();*/
        clearNow += clear();
    }
    //cout<<' '<<cleared<<endl;
    return clearNow;
}

void play(int i)
{
    int last[5][7],t,c;
    rst l = stack[i-1];
    if (i>n)
    {
        if (s==cleared)
        {
            for (int j = 0; j<n; j++)
                printf("%d %d %d\n", stack[j].x, stack[j].y, stack[j].direct);
            exit(0);
        }
        else
            return;
    }
    for (int j = 0; j<4; j++)
        for (int k = 0; k<7; k++)
            if (a[j][k]!=0&&a[j][k]!=a[j+1][k])
            {
                if (i>1&&stack[i-2].x==j&&stack[i-2].y==k&&stack[i-2].direct==1) continue;
                t = a[j][k];
                a[j][k] = a[j+1][k];
                a[j+1][k] = t;
                memcpy(last,a,sizeof(a));
                stack[i-1].x = j; stack[i-1].y = k; stack[i-1].direct = 1;
                c = clear();
                play(i+1);
                stack[i-1] = l;
                memcpy(a,last,sizeof(a));
                cleared -= c;
                t = a[j][k];
                a[j][k] = a[j+1][k];
                a[j+1][k] = t;
            }
    for (int j = 1; j<5; j++)
        for (int k = 0; k<7; k++)
            if (a[j][k]!=0&&a[j-1][k]==0&&a[j][k]!=a[j-1][k])
            {
                if (i>1&&stack[i-2].x==j&&stack[i-2].y==k&&stack[i-2].direct==-1) continue;
                t = a[j][k];
                a[j][k] = a[j-1][k];
                a[j-1][k] = t;
                memcpy(last,a,sizeof(a));
                stack[i-1].x = j; stack[i-1].y = k; stack[i-1].direct = -1;
                c = clear();
                play(i+1);
                stack[i-1] = l;
                memcpy(a,last,sizeof(a));
                cleared -= c;
                t = a[j][k];
                a[j][k] = a[j-1][k];
                a[j-1][k] = t;
            }
}

int main()
{
    cin>>n;
    for (int i = 0 ;i<5; i++)
    {
        j = 0; cin>>t;
        while (t!=0)
        {
            s++;
            block[t]++;
            a[i][j++] = t;
            cin>>t;
        }
    }
    for (int i = 1; i<=10; i++)
        if (block[i]!=0&&block[i]<3)
        {
            cout<<-1;
            return 0;
        }
    //print();
    play(1);
    if (s!=cleared) cout<<-1;

    return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...