>Description
相信大家都玩过“俄罗斯方块”游戏吧,“俄罗斯方块”是一个有趣的电脑小游戏,现有一个有C列、行不受限定游戏平台,每一次下落的方块是下列的7个图形的一种:
在下落的过程中,游戏者可以作90、 180或270 度旋转,还可以左右移动,对于每一次方块落地,我们要求方块的每一部分都必须与地面(最底面或己落下的方块上表面)接触,例如,有一个宽度为6列的平台,每一列的初始高度(已经占用的方格数)分别为2, 1, 1, 1, 0 和 1。编号为5的方块下落,有且仅有5种不同的落地方法:
现给出每一列的初始高度和下落方块的形状,请你编写一个程序,求出落地的方法总数,也就是落地后,地表面形成的不同的形状总数。
>Input
第一行为二个整数C和P,1 ≤ C ≤ 100, 1 ≤ P ≤ 7,表示列数和下落方块的编号
第二行共有用一个空隔隔开的C个整数,每一个数字在 0 到 100,之间(包含0和100),表示每一列的初始高度
>Output
输出为一个整数,表示落地的方法总数
>Sample Input
Input1
6 5
2 1 1 1 0 1
Input2
5 1
0 0 0 0 0
Input3
9 4
4 3 5 4 6 5 7 6 6
>Sample Output
Output1
5
Output2
7
Output3
1
>解题思路
大模拟 打得我头都大了
打表:输入每一种方法的每一种转化方式中,每一列底下的空格与其它列中最多的空格的差(因为有些图形是凹凸不平的),然后在枚举每一个图形在的位置,看看每一列原来的高度加上这个的高度是不是一样,如果一样就累加答案。
>代码
#include<iostream>
#include<cstdio>
using namespace std;
int n,p,ans,cc,a[105],f[8][5][5],s[8][4],lhq[8];
void aka()
{
f[3][1][1]=f[3][1][2]=f[3][2][2]=1;
f[4][1][2]=f[4][1][3]=f[4][2][1]=1;
f[5][2][2]=f[5][3][2]=f[5][4][1]=1;
f[6][3][1]=1;
f[6][2][2]=2;
f[7][3][3]=1;
f[7][4][1]=2; //图形的高度
s[1][1]=s[1][3]=1; s[1][2]=s[1][4]=4;
s[2][1]=s[2][2]=s[2][3]=s[2][4]=2;
s[3][1]=s[3][3]=3; s[3][2]=s[3][4]=2;
s[4][1]=s[4][3]=3; s[4][2]=s[4][4]=2;
s[5][1]=s[5][3]=3; s[5][2]=s[5][4]=2;
s[6][1]=s[6][3]=3; s[6][2]=s[6][4]=2;
s[7][1]=s[7][3]=3; s[7][2]=s[7][4]=2; //每一个图形的不同方式的宽度
lhq[2]=1; lhq[5]=lhq[6]=lhq[7]=4; lhq[1]=lhq[3]=lhq[4]=2; //每一个图形的方式数(有些不同方式的图形是一样的)
}
int main()
{
aka();
scanf("%d%d",&n,&p);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int k=1;k<=lhq[p];k++) //枚举方式
for(int i=1;i<=n-s[p][k]+1;i++) //图形的起始位置
{
ans++;
cc=a[i]+f[p][k][1];
for(int j=2;j<=s[p][k];j++) //图形长度
if(a[i+j-1]+f[p][k][j]!=cc)
{
ans--; break;
}
}
printf("%d",ans);
return 0;
}