【ccf認證】201604-2 俄羅斯方塊(c/c++)

試題編號: 201604-2
試題名稱: 俄羅斯方塊
時間限制: 1.0s
內存限制: 256.0MB
問題描述:

問題描述

  俄羅斯方塊是俄羅斯人阿列克謝·帕基特諾夫發明的一款休閒遊戲。
  遊戲在一個15行10列的方格圖上進行,方格圖上的每一個格子可能已經放置了方塊,或者沒有放置方塊。每一輪,都會有一個新的由4個小方塊組成的板塊從方格圖的上方落下,玩家可以操作板塊左右移動放到合適的位置,當板塊中某一個方塊的下邊緣與方格圖上的方塊上邊緣重合或者達到下邊界時,板塊不再移動,如果此時方格圖的某一行全放滿了方塊,則該行被消除並得分。
  在這個問題中,你需要寫一個程序來模擬板塊下落,你不需要處理玩家的操作,也不需要處理消行和得分。
  具體的,給定一個初始的方格圖,以及一個板塊的形狀和它下落的初始位置,你要給出最終的方格圖。

輸入格式

  輸入的前15行包含初始的方格圖,每行包含10個數字,相鄰的數字用空格分隔。如果一個數字是0,表示對應的方格中沒有方塊,如果數字是1,則表示初始的時候有方塊。輸入保證前4行中的數字都是0。
  輸入的第16至第19行包含新加入的板塊的形狀,每行包含4個數字,組成了板塊圖案,同樣0表示沒方塊,1表示有方塊。輸入保證板塊的圖案中正好包含4個方塊,且4個方塊是連在一起的(準確的說,4個方塊是四連通的,即給定的板塊是俄羅斯方塊的標準板塊)。
  第20行包含一個1到7之間的整數,表示板塊圖案最左邊開始的時候是在方格圖的哪一列中。注意,這裏的板塊圖案指的是16至19行所輸入的板塊圖案,如果板塊圖案的最左邊一列全是0,則它的左邊和實際所表示的板塊的左邊是不一致的(見樣例)

輸出格式

  輸出15行,每行10個數字,相鄰的數字之間用一個空格分隔,表示板塊下落後的方格圖。注意,你不需要處理最終的消行。

樣例輸入

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 0 0 0 1 1 1 1
0 0 0 0 1 0 0 0 0 0
0 0 0 0
0 1 1 1
0 0 0 1
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 1 1 1 1 1
0 0 0 0 1 1 0 0 0 0

 

基本思路:

根據題中:當板塊中某一個方塊的下邊緣與方格圖上的方塊上邊緣重合或者達到下邊界時,板塊不再移動。得:

1、定義2個二維數組a和t,分別存儲方格圖和板塊。

2、定義數組ft[i],表示板圖中第i列的方塊的下邊緣;定義數組fa[i],表示方格圖中第i列的方塊的上邊緣。

3、遍歷每行(實際爲模擬方塊下落過程),遍歷方格圖對應的那4列。若ft[i]+1==fa[i](即該方塊的下邊緣與方格圖上的方塊上邊緣重合)或ft[i]==15(即該方塊達到下邊界)時,把板塊中的方塊對應放入方格圖中。循環結束,打印輸出。

 

AC代碼:

#include <iostream>
#include <cstdio>

using namespace std;

int main(){
    int a[16][11];
    int t[5][5];
    int n;

    //輸入
    for(int i=1;i<=15;i++)
        for(int j=1;j<=10;j++)
            scanf("%d",&a[i][j]);
    for(int i=1;i<=4;i++)
        for(int j=1;j<=4;j++)
            scanf("%d",&t[i][j]);
    scanf("%d",&n);

    //記錄圖的上邊緣和板塊的下邊緣
    int fa[11]={0};//第i列的第幾個爲上邊緣
    for(int i=1;i<=15;i++){
        for(int j=1;j<=10;j++){
            if(a[i][j]==1&&fa[j]==0) fa[j]=i;
        }
    }

    int ft[5]={0};//第i列的第幾個爲下邊緣
    for(int i=4;i>=1;i--){
        for(int j=1;j<=4;j++){
            if(t[i][j]==1&&ft[j]==0) ft[j]=i;
        }
    }

    //挨邊
    int flag=0;
    int f[5][5]={0};//記錄板塊中方塊位置是否已轉移至圖
    for(int i=0;i<15;i++){
        for(int j=n;j<n+4;j++){
            //結束
            int k=j-n+1;
            int en=-2;
            //printf("?\n");
            if(ft[k]!=0) en=ft[k]+i;
            if((en+1==fa[j])||(en==15)){
                for(int ii=i+1,ti=1;ii<=15&&ti<=4;ii++,ti++){
                    for(int jj=n,tj=1;jj<n+4&&jj<=10&&tj<=4;jj++,tj++){
                        if(a[ii][jj]==0&&t[ti][tj]==1&&f[ti][tj]==0){
                            a[ii][jj]=t[ti][tj];
                            f[ti][tj]=1;
                            //printf("a[%d][%d]=t[%d][%d]=%d\n",ii,jj,ti,tj,a[ii][jj]);
                        }
                    }
                }
                flag=1;
                break;
            }
        }
        if(flag==1) break;
    }

    //打印
    //printf("--------------\n");
    for(int i=1;i<=15;i++){
        for(int j=1;j<=10;j++)
            printf("%d ",a[i][j]);
        printf("\n");
    }


    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章