俄罗斯方块【模拟】

>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;
}

猜你喜欢

转载自blog.csdn.net/qq_43010386/article/details/90731048