思路:细节还挺多的一个模拟题。从底向上判断有没有能放下这四个块的空位,如果有的话判断它所在的列上面有没有块挡着。
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long ll;
int a[20][20],b[5][5],vis[15];
bool check(int x,int y)
{
memset(vis,0,sizeof vis); //清空标记数组
for(int i=x-3;i<=x;i++)
for(int j=y;j<y+4;j++)
if(a[i][j]&&b[i-(x-3)][j-y]) //如果有一个地方不是空位,返回false
return false;
for(int i=x-3;i<=x;i++) //如果有放的下四个块的空位
for(int j=y;j<y+4;j++)
if(b[i-(x-3)][j-y]&&!vis[j]) //判断这一列上放是否有块阻挡它落下
{
vis[j]=1;
for(int k=i-1;k>=1;k--)
if(a[k][j])
return false;
}
return true;
}
void work(int x,int y) //把块放入它落下的位置
{
for(int i=x-3;i<=x;i++)
for(int j=y;j<y+4;j++)
if(b[i-(x-3)][j-y])
a[i][j]=1;
}
void init() //如果4x4的块最后一行或两行是0行,移到最上方
{
int flag=0,num=0;
for(int i=3;i>=0;i--)
{
for(int j=0;j<4;j++)
if(b[i][j])
flag=1;
if(flag==0)
num++;
}
for(int i=3;i>=0;i--)
for(int j=0;j<4&&i-num>=0;j++)
swap(b[i][j],b[i-num][j]);
}
int main()
{
for(int i=1;i<=15;i++)
for(int j=1;j<=10;j++)
cin>>a[i][j];
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
cin>>b[i][j];
int cal;
cin>>cal;
init();
for(int i=15;i>=1;i--)
if(check(i,cal))
{
work(i,cal);
break;
}
for(int i=1;i<=15;i++)
{
for(int j=1;j<=10;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
return 0;
}