鄙人不才,此中鄙陋甚多,望海涵!!!
这个题是真的烦,讨厌模拟啊,基本思路是去寻找矛盾,我们可以把对应2方块数字加和的过程比作方块下落的过程,而在方块下落的过程中怎样算是出现了矛盾呢?那就是加和的过程中产生数字2,我们可以记录每个产生矛盾前的关键量,比如此时加和的是g(15*10的方格图)
中的哪一行与d(4*4的方格图)
相加产生了矛盾,这样矛盾产生的前一个行就是得到答案时要加和的行数了(其实我描述的不是很清楚,但是结合代码来了解就可以懂了),但这里还要特别注意的是可能不会产生矛盾,那么我们就需要另外处理了!比如下面这个例子!
输入
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0
1 1 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0
1 1 1 0
0 0 1 0
0 0 0 0
0 0 0 0
3
输出
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0
1 1 1 1 1 0 1 1 1 1
0 0 0 0 1 0 0 0 0 0
在这个例子中,不论怎么加都不会出现矛盾,需要特殊处理,详细见代码!
C++ code
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int g[30][30],d[10][10],dc[10][10];
int main()
{
for(int i=1;i<=15;i++)
for(int j=1;j<=10;j++)
scanf("%d",&g[i][j]);
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
scanf("%d",&d[i][j]);
int x,y=0;
cin>>x;
for(int i=1;i<=16;i++)
{
memcpy(dc,d,sizeof d);
for(int j=x;j<=x+3;j++)
for(int k=0;k<4;k++)
dc[k+1][j-x+1]+=g[i+k][j];
int flag=0;
for(int j=1;j<=4;j++)
for(int k=1;k<=4;k++)
if(dc[j][k]==2) flag=1;
if(!flag) y=i;
else break;
}
if(y==16)
{
int cnt=0,flag=0;
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)
if(d[i][j])
{
cnt++;
if(cnt==4)
{
flag=i;
break;
}
}
if(flag) break;
}
y=15-flag+1;
}
for(int i=y;i<=y+3;i++)
for(int j=x;j<=x+3;j++)
g[i][j]+=d[i-y+1][j-x+1];
for(int i=1;i<=15;i++)
{
for(int j=1;j<=10;j++) printf("%d ",g[i][j]);
puts("");
}
return 0;
}