CCF 2016-04模拟俄罗斯方块下落问题
这道题调试好久,出现越来越多不能理解的错甚至觉得是Dev坏掉了(毕竟新手一个渣TAT),先上题。。。。
刚看到题目是有点傻掉了,这才刚到第二题QAQ,讲道理不能这么玩,于是又瞪大双眼再读题
你需要写一个程序来模拟板块下落,你不需要处理玩家的操作,也不需要处理消行和得分
所以啊只需要模拟下落过程找到最终下落的位置就好
这道题确实有点意思,最开始想了很久,感觉方法应该有很多,这是最后程序实现的思路:根据输入的方块形状以及最后一行的输入参数来求出方块各点在大图中对应的位置坐标,然后依次求出每一块下落的最大距离取最小值,方法是每次横坐标加1判断大图对应位置处是1是0,是0的话继续下落,直至为1表示有阻碍不能继续下降,累加求下降距离。然后根据最小下落距离将方块最终降落在大图里的位置赋值1。最先有想过先遍历输入的四个小方块坐标找到横坐标最大的那个,然后以它为基准直接计算下降距离就好,但是大图最下面几行的方块分布是未知、不均匀的,最终降落位置的确定应该是以大图下方的阻碍分布为主。
以下是源代码,C语言实现~
#include<stdio.h>
int main()
{
int min=9999;
int a,b;
int count=0;
int n, i, j;
int k = 0;
int load[16][11];
int aim[5][5];
int store[5][3];
for (i = 1; i <= 15; i++)
for (j = 1; j <= 10; j++)
scanf("%d", &load[i][j]);
for (i = 1; i <= 4; i++)
for (j = 1; j <= 4; j++)
scanf("%d", &aim[i][j]);
scanf("%d", &n);
for (i = 1; i <= 4; i++)
for (j = 1; j <= 4; j++)
{
if (aim[i][j] == 1)
{
k++;
store[k][1] = i;
store[k][2] = j + n - 1;
}
}
for(i=1;i<=4;i++)
{
a=store[i][1];
b=store[i][2];
while(!load[a+1][b])
{
count++;
a++;
}
if(count<min)
{
min=count;
count=0;
}
else
count=0;
}
if(min<=14)
{
for(i=1;i<=4;i++)
{
a=store[i][1];
b=store[i][2];
load[a+min][b]=1;
}
}
for (i = 1; i <= 15; i++)
for (j = 1; j <= 10; j++)
{
printf("%d ", load[i][j]);
if (j == 10)
printf("\n");
}
return 0;
}
遗留的问题:下面的这段代码最初是用for循环写的,现在仍然想不通为什么会出错
while(!load[a+1][b])
{
count++;
a++;
}
for ( ; load[a + 1][b] = 0, a<15; a++)
count++;
以下两幅图分别是正确输出与错误输出:
最大的不同就是,使用for循环最后输出竟然把原来大图分布最后一行第四个1莫名其妙变成了0,欲哭无泪啊。。。
于是又进行了第二组测试:
所以猜测应该是在遍历四个小方块坐标求最小下落距离过程中,中间某一步把原图值改变了导致最终求得的最小下落距离错误。
接着,基于测试2数据,对程序进行调试:
i=1,小方块对应大图坐标[2][4]横坐标自增求最大下落距离,min=13没有错误
i=2,小方块对应大图坐标[2][5]横坐标自增求最大下落距离时,发现了错误所在........
当a即横坐标自增至14时,正当下一步应该判断原图坐标[14+1][5]位置是1还是0,该点坐标神奇地,,,自己变成了,,,0,0,0,0,0, /*渣渣表示内心受到暴击*/
佯装镇定,又对第一组测试数据再次调试,依然如是,作为限制下落条件的阻碍,坐标为[14+1][5]位置的方块再次改变了~
所以,for循环有毒啊,本来还很得意地用了两个限制条件,,,,自作聪明,,,,然而这个错误现在还是不太能理解,所以记录在这儿,想通了以后再来完善。
while循环人畜无害好可爱的说嘤嘤嘤~