ccf 201604-2 俄罗斯方块

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

ccf 201604-2 俄罗斯方块

题外话:这个题目挺有意思的,没有涉及到什么图论里面的算法,也不是什么图的搜索,咋一看吓死人无从下手,说实话我一开始也有点摸不着头脑,因为这个才是第二题,信息量比较大,正常人看完题目首先想到的是找规律,这个题目要是找规律你就亏大了,因为你会浪费很多时间,而且找完规律也很难拿到100分,我第一次做80分,剩下两个用例我一直没想出来,不知道哪两种特殊情况我还没想到。ccf就喜欢出这种题目,叫做“动态模拟执行”,特别是图里面的,你可以看每年ccf出的题目,五道题至少有三道是图,当然用的算法是不一样的。

解题思路:
1.我们可以模拟俄罗斯方块下降的过程直到不再下降,最后输出整个矩阵,程序就结束了。
2.我们需要输入的有两个矩阵,大矩阵15x10记作a,小矩阵4x4记作b(就是存放俄罗斯方块的),我们需要把整个矩阵a存起来,因为题目的答案就是对最后的a输出。矩阵b不需要存储内容,因为我们只要从b矩阵里面把俄罗斯方块的各个点记住即可。
3.初始状态我们将矩阵b放入矩阵a里面,需要将坐标统一为矩阵a的坐标,矩阵b在矩阵a中的起始位置,列:b[i].y+nl-1;行:找到原矩阵b中最大的一行,也就是最下面的那个行号,则等于最大的行赋值为0,小于的赋值为其行与最大的行号之差。然后开始下降过程,看代码即可;该程序是100分通过。

#include<iostream>
#include<algorithm>
using namespace std;
int a[20][15],b;
int nod_size=0;
struct node
{
    int x;
    int y;
}nod[25]={0};
bool cmp(node n1,node n2)
{
    return n1.x<n2.x;
}
int main()
{
    int nl,ct=0;
    for(int i=0;i<15;++i)
    {
        for(int j=0;j<10;++j)
        {
            scanf("%d",&a[i][j]);
        }
    }
    for(int i=0;i<4;++i)
    {
        for(int j=0;j<4;++j)
        {
            scanf("%d",&b);
            if(b==1)
            {
                nod[ct].x=i;
                nod[ct].y=j;
                nod_size++;
                ++ct;
            }
        }
    }
    scanf("%d",&nl);
    sort(nod,nod+nod_size,cmp);
    int nod_max_x=nod[nod_size-1].x;
    for(int i=0;i<nod_size;++i)
    {
        if(nod[i].x>=nod_max_x)
        {
            nod[i].x=0;
        }
        else
        {
            nod[i].x-=nod_max_x;
        }
        nod[i].y+=nl-1;
    }
    bool flag=true;
    while(flag)
    {
        for(int i=0;i<nod_size;++i)
        {
            if(nod[i].x>=14 || a[nod[i].x+1][nod[i].y]==1)
            {
                flag=false;
                break;
            }
        }
        for(int i=0;i<nod_size && flag;++i)
        {
            nod[i].x++;
        }
    }
    for(int i=0;i<nod_size;++i)
    {
        a[nod[i].x][nod[i].y]=1;
    }
    for(int k=0;k<15;++k)
    {
        for(int m=0;m<10;++m)
        {
            printf("%d",a[k][m]);
            if(m<9)
            {
                printf(" ");
            }
        }
        printf("\n");
    }
    return 0;
}
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值