CCF認證 201604 俄羅斯方塊
俄羅斯方塊是俄羅斯人阿列克謝·帕基特諾夫發明的一款休閒遊戲。
遊戲在一個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.將4*4矩陣中的方塊摳出來,用兩個陣列x[]和y[]來表示其中的位置。2.將x[]和y[]置於15*10的矩陣中,不斷的下沉,碰到1就停止,位置就為當前y軸減去1。3.如果一直有一個方塊,碰到最底下(15*10的邊界),將整個迴圈結束。
package csp201604;
import java.util.Scanner;
/**
* 俄羅斯方塊
* @author SUN
*
*/
public class Main{
public static void main(String[] args) {
Main.run();
}
public static void run(){
Scanner sc = new Scanner(System.in);
int[][] arr = new int[15][10];
int[][] arrSqu = new int[4][4];
//將輸入的方格圖存入陣列
for(int i=0;i<15;i++){
for(int j=0;j<10;j++){
arr[i][j] = sc.nextInt();
}
}
//將方塊存入陣列
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
arrSqu[i][j] = sc.nextInt();
}
}
//獲取方塊將要下沉的位置,偏移
int column = sc.nextInt();
//首先獲取這個方塊每個節點在4*4矩陣中的位置
int[] x = new int[4];
int[] y = new int[4];
int z = 0;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(arrSqu[i][j]==1){
x[z]=i;
y[z]=j+column-1;
z++;
}
}
}
boolean flag = true;
int count=0;
int offset =0;
outer:
while(flag){
for(int i=0;i<4;i++){
//判斷最下面的邊界,如果有一個方塊到了最下面,直接結束下沉
if((x[i]+offset)==14){
for(int j=0;j<4;j++){
arr[x[j]+offset][y[j]]=1;
}
break outer;
}
if(arr[x[i]+offset][y[i]]==0){//不斷的下沉
count++;
}
}
if(count==4){
offset++;
count=0;
}else{
for(int i=0;i<4;i++){
arr[x[i]+offset-1][y[i]]=1;
}
flag = false;
}
}
//遍歷下沉後的矩陣
for(int i=0;i<15;i++){
for(int j=0;j<10;j++){
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
}