SSL P1963 提高组 俄罗斯方块

题目大意:
“俄罗斯方块”是一个有趣的电脑小游戏,现有一个有C列、行不受限定游戏平台,每一次下落的方块是下列的7个图形的一种:
这里写图片描述

在下落的过程中,游戏者可以作90、 180或270 度旋转,还可以左右移动,对于每一次方块落地,我们要求方块的每一部分都必须与地面接触,例如,
有一个宽度为6列的平台,每一列的初始高度(已经占用的方格数)分别为2, 1, 1, 1, 0 和 1。编号为5的方块下落,有且仅有5种不同的落地方法:
这里写图片描述
现给出N列的初始高度,以及使用的是第P种图形,求出落地的方案总数。
1 ≤ C ≤ 100, 1 ≤ P ≤ 7
高度介于在 0 到 100,之间

题解:
我们分析题目发现因为图形的下表面全部,必须要与地面接触,即方块的每一列必须紧紧贴着地面。
所以直接将每个图形每种出现的情况降落所需要满足的要求枚举一遍即可。

时间复杂度:O(N)

var
    a:array [0..101] of longint;
    i,n,m,ans:longint;

procedure workone;
begin
    for i:=4 to n do
      if (a[i]=a[i-1]) and (a[i]=a[i-2]) and (a[i]=a[i-3])
         then inc(ans);
    ans:=ans+n;
end;

procedure worktwo;
begin
    for i:=2 to n do
      if a[i]=a[i-1] then inc(ans);
end;

procedure workthree;
begin
    for i:=3 to n do
      if (a[i]=a[i-1]+1) and (a[i]=a[i-2]+1)
         then inc(ans);
    for i:=2 to n do
      if a[i]=a[i-1]-1
         then inc(ans);
end;

procedure workfour;
begin
    for i:=1 to n-2 do
      if (a[i]=a[i+1]+1) and (a[i]=a[i+2]+1)
         then inc(ans);
    for i:=2 to n do
      if a[i]=a[i-1]+1
         then inc(ans);
end;

procedure workfive;
begin
    for i:=3 to n do
      if ((a[i]=a[i-1]) and (a[i]=a[i-2])) or
         ((a[i]=a[i-1]+1) and (a[i]=a[i-2])) then inc(ans);
    for i:=2 to n do
      if (a[i]=a[i-1]+1) or (a[i]=a[i-1]-1)
         then inc(ans);
end;

procedure worksix;
begin
    for i:=3 to n do
      if ((a[i]=a[i-1]) and (a[i]=a[i-2])) or
         ((a[i]=a[i-1]) and (a[i]=a[i-2]+1)) then inc(ans);
    for i:=2 to n do
      if (a[i]=a[i-1]) or (a[i]=a[i-1]-2) then inc(ans);
end;

procedure workseven;
begin
    for i:=3 to n do
      if ((a[i]=a[i-1]) and (a[i]=a[i-2])) or
         ((a[i]=a[i-1]-1) and (a[i]=a[i-2]-1)) then inc(ans);
    for i:=2 to n do
      if (a[i]=a[i-1]+2) or (a[i]=a[i-1]) then inc(ans);
end;

begin
    readln(n,m);
    for i:=1 to n do read(a[i]);
    ans:=0;
    case m of
         1:workone;
         2:worktwo;
         3:workthree;
         4:workfour;
         5:workfive;
         6:worksix;
         7:workseven;
    end;
    writeln(ans);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值