题外话:这个题目挺有意思的,没有涉及到什么图论里面的算法,也不是什么图的搜索,咋一看吓死人无从下手,说实话我一开始也有点摸不着头脑,因为这个才是第二题,信息量比较大,正常人看完题目首先想到的是找规律,这个题目要是找规律你就亏大了,因为你会浪费很多时间,而且找完规律也很难拿到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;
}