對下降的方塊確定上下左右界限,在地圖中找到下降的起始列和結束列(和下降塊匹配),遍歷地圖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個小方塊組成的板塊從方格圖的上方落下,玩家可以操作板塊左右移動放到合適的位置,當板塊中某乙個方塊的下邊緣與方...