201604 2 俄羅斯方塊

2021-10-22 16:26:47 字數 4565 閱讀 1499

對下降的方塊確定上下左右界限,在地圖中找到下降的起始列和結束列(和下降塊匹配),遍歷地圖map,直到當前的位置的值和下降塊該處的值相與,如果=1,說明找到了第乙個可能是界限的行,然後從當前行進行遍歷,遍歷的方法是:

假如下降塊為:

0 1 1 0

0 0 1 0

0 0 1 0

0 0 0 0

分離之後的下降塊為:

1 10 1

0 1即只保留包含整個下降塊的矩陣,然後用該矩陣去遍歷分離出的map

先從地圖map中確認起始的列:n-1+left_boundary,結束列:n-1+right_boundary

測試資料:

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

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

0 0 0 0 1 0 0 0 0 0

0 1 1 0

0 0 1 0

0 0 1 0

0 0 0 0

3

裁剪後的map為:

遍歷分離的map發現第乙個可能在此停止下降的點:

用改行與下降塊的最後一行進行匹配,如果不滿足對應元素相與為1的情況,就將其增加為兩行,與下降塊的倒數兩行進行判斷

【注意】陣列map增設一行,即最後一行全設為1,防止下降過程中無障礙物陣列下標訪問越界的情況,同時便於判斷。

【說明】下降停留行位置的判斷例項:

下降塊:(此處新設的資料,與上例的資料不同)

1 10 1

0 1遍歷得到的第乙個對應位置相與不為0的map的行:

1 0用改行與最後一行:0 1匹配,0 && 1 = 0, 1 && 0 = 0,不滿足條件,則方格可以繼續下降乙個單位,於是就變為:

0 10 1

與map的 1 0及其下一行匹配,假設為

1 01 0

按照以上方法,仍然不匹配,繼續下降乙個單位:

1 10 1

0 1與

1 01 0

1 0匹配,由於1 && 1 = 1,滿足條件,得到降落點所在行,然後根據得到的行標記,用切割後的下降塊矩陣更新map。

經檢查,該**不完整,仍然存在bug…在中間的障礙物,無法正確檢測。

#include

#include

using

namespace std;

const

int row =15;

const

int col =10;

const

int n =4;

int map[row +1]

[col]

;int block[n]

[n];

int lower_boundary =

0, upper_boundary =3;

int left_boundary =

3, right_boundary =0;

intmain

(int argc,

char

const

*ar**)

}for

(int j =

0; j < col; j++

)for

(int i =

0; i < n; i++)}

}// printf("upper_boundary:%d\n", upper_boundary);

// printf("lower_boundary:%d\n", lower_boundary);

// printf("left_boundary:%d\n", left_boundary);

// printf("right_boundary:%d\n", right_boundary);

int n;

cin >> n;

// 從左邊的第n-1列開始下落

// 找到第乙個不為0的障礙物節點

int flag_x = row;

bool flag =

false

;// cout << n - 1 + left_boundary << endl;

// cout << n + right_boundary + 1 << endl;

for(

int i =

0; i < row +1&&

!flag; i++)}

}// printf("flag_x=%d\n", flag_x);

flag =

false

;int stop_x = flag_x;

for(

int i = lower_boundary, index =

0; i >= upper_boundary - index &&

!flag; i--)}

if(!flag)

}// printf("stop_x=%d\n", stop_x);

// 更新格仔狀態

int start_x = stop_x -1;

for(

int i = lower_boundary; i >= upper_boundary; i--

, start_x--)}

// output

for(

int i =

0; i < row; i++

) cout << endl;

}return0;

}

參考:

主要思想在於構建下降的座標系,下降塊(4*4的矩陣)block左上角為座標原點,每次遍歷將座標原點下移乙個單位,直到滿足可以停落的條件,然後用之前標記的block中為1的障礙物的座標去填充背景圖backmap即可。

#include

using

namespace std;

const

int row =15;

const

int col =10;

const

int n =4;

int backmap[row +1]

[col]

;int block[n]

[n];

struct coord

} coords[n]

;int

main

(int argc,

char

const

*ar**)

}for

(int i =

0; i < n; i++)}

cin >> col;

for(

int j =

0; j < col; j++

)// 記錄block的不為0的障礙塊的相對座標

int k =0;

for(

int i = n -

1; i >=

0; i--)}

}for

(int i =

0; i < n; i++

)// 處理下降

row =

1, col--

;bool flag =

false

;while

(!flag)}if

(!flag)

row++

;else

break;}

row--

;// 得到滿足降落的座標

for(

int i =

0; i < n; i++

)for

(int i =

0; i < row; i++

) cout << endl;

}return0;

}

【ps】使用兩個break的原因:break只能夠一層一層地跳出迴圈,不能跳出多重迴圈,如果要直接跳出多重迴圈,需要使用goto語句,但並不推薦使用,goto破壞了**的結構。

201604 2 俄羅斯方塊

試題編號 201604 2 試題名稱 俄羅斯方塊 時間限制 1.0s 記憶體限制 256.0mb 問題描述 問題描述 俄羅斯方塊是俄羅斯人阿列克謝 帕基特諾夫發明的一款休閒遊戲。遊戲在乙個15行10列的方格圖上進行,方格圖上的每乙個格仔可能已經放置了方塊,或者沒有放置方塊。每一輪,都會有乙個新的由4...

201604 2 俄羅斯方塊

解題思路 用乙個二維陣列mp儲存原來的方塊圖,用另乙個二維陣列tmp儲存臨時的方塊圖,先把tmp完全按照mp完全複製,然後加入新的方塊,統計出1的個數,然後使用to down函式將加入的新方塊每次往下移動乙個格仔,如果移動過程中tmp中1的個數變少了,說明新方塊覆蓋了原來的格仔,網上回溯乙個格仔就是...

CCF CSP 俄羅斯方塊(201604 2)

問題描述 俄羅斯方塊是俄羅斯人阿列克謝 帕基特諾夫發明的一款休閒遊戲。遊戲在乙個15行10列的方格圖上進行,方格圖上的每乙個格仔可能已經放置了方塊,或者沒有放置方塊。每一輪,都會有乙個新的由4個小方塊組成的板塊從方格圖的上方落下,玩家可以操作板塊左右移動放到合適的位置,當板塊中某乙個方塊的下邊緣與方...