俄羅斯方塊 tetris
【題意】
俄羅斯方塊遊戲,在乙個寬度為n高度為h的矩陣中進行,給定初始狀態,每次給定乙個形狀的方塊,將它放到最靠左進行最少旋轉次數可不出現「洞」(就是說同一列方塊之間有縫隙)且加入後最高高度不超過h的位置,並輸出這個位置,跟一般的俄羅斯方塊一樣,一行滿了便會消行
各種編號對應的方塊
****
【輸入】
第一行n、m、h(皆小於等於100000)
接下來m行每行乙個數字表示加入的方塊的形狀
【輸出】
對於每次加入輸出其位置
十分麻煩的題
首先需要乙個函式(這裡是could)來判斷某位置是否能放入乙個某形狀的方塊
然後用線段樹來維護,維護兩個值,區間內高度最低值和用乙個7位2進製數表示的以區間內的點為起點每種形狀是否能放入
那麼對於每次插入,查詢最靠左的點,並更新有關的最多七個點,總查詢並更新複雜度為mlogn
對於消行,每次重建線段樹即可,消行次數最多為4*m/n,每次重建為nlogn,所以總重建複雜度為mlogn
雖然常數比較大,但這個複雜度對於時限3s的本題還是很輕鬆的
program tetris;
const
plus:array [0..6,1..4,0..3] of longint
=(((3,1,0,0),(1,1,2,0),(1,3,0,0),(2,1,1,0)),
((1,3,0,0),(1,1,2,0),(3,1,0,0),(2,1,1,0)),
((1,2,1,0),(2,2,0,0),(0,0,0,0),(0,0,0,0)),
((1,2,1,0),(2,2,0,0),(0,0,0,0),(0,0,0,0)),
((1,2,1,0),(1,3,0,0),(1,2,1,0),(3,1,0,0)),
((2,2,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)),
((1,1,1,1),(4,0,0,0),(0,0,0,0),(0,0,0,0))
);dif:array [0..6] of longint=(4,4,2,2,4,1,2);
long:array [0..6,1..4] of longint
=((2, 3, 2, 3 ),
(2, 3, 2, 3 ),
(3, 2, 0, 0 ),
(3, 2, 0, 0 ),
(3, 2, 3, 2 ),
(2, 0, 0, 0 ),
(4, 1, 0, 0 )
);need:array [0..6,1..4,0..2] of longint
=(((-2,9,9), (0,1,9), (0,9,9), (0,0,9) ),
((2,9,9), (0,0,9), (0,9,9), (-1,0,9) ),
((0,-1,9), (1,9,9), (9,9,9), (9,9,9) ),
((1,0,9), (-1,9,9), (9,9,9), (9,9,9) ),
((1,-1,9), (1,9,9), (0,0,9), (-1,9,9) ),
((0,9,9), (9,9,9), (9,9,9), (9,9,9) ),
((0,0,0), (9,9,9), (9,9,9), (9,9,9) )
);var minn,tot,h,n,m,i,j,k,t:longint;
high:array [0..100001] of longint;
min,left,right,status:array [0..200001] of longint;
function could (now,form:longint):longint;
var ok:boolean;
i,j,k:longint;
begin
for i:=1 to dif[form] do
begin
if (high[now]+plus[form,i,0]>h)or(now+long[form,i]-1>n) then continue;
ok:=true;
for j:=0 to long[form,i]-2 do
if (high[now+j]-high[now+j+1]<>need[form,i,j])
or(high[now+j+1]+plus[form,i,j+1]>h)
then
begin
ok:=false;
break
end;
if ok then exit(i);
end;
exit(0);
end;
procedure change (who,l,r,now:longint);
var i:longint;
begin
if l=r then
begin
min[now]:=high[who];
status[now]:=0;
for i:=0 to 6 do
if could(who,i)<>0 then status[now]:=status[now] or (1 shl i);
exit;
end;
if who<=(l+r) div 2 then change(who,l,(l+r) div 2,left[now])
else change(who,(l+r) div 2+1,r,right[now]);
status[now]:=status[left[now]] or status[right[now]];
if min[left[now]]0 then status[now]:=status[now] or (1 shl i);
exit;
end;
mid:=(s+e) div 2;
inc(tot);
left[now]:=tot;
inc(tot);
right[now]:=tot;
quick(s,mid,left[now]);
quick(mid+1,e,right[now]);
status[now]:=status[left[now]] or status[right[now]];
if min[left[now]]0 then
change(now-i,1,n,0);
if min[0]<>0 then
begin
for i:=1 to n do
high[i]:=high[i]-min[0];
build;
end;
end;
begin
assign(input,'tetris.in');
reset(input);
assign(output,'tetris.out');
rewrite(output);
read(n,m,h);
minn:=maxlongint;
for i:=1 to n do
begin
read(high[i]);
if high[i]
俄羅斯方塊高階 AI俄羅斯方塊
前文回顧 致青春 python實現俄羅斯方塊 人工智慧大火的今天,如果還是自己玩俄羅斯方塊未免顯得太low,為什麼不對遊戲公升級,讓機器自己去玩俄羅斯方塊呢?有了這個想法之後利用週六週日兩天的時間去蒐集了大量的資料,在電腦宕機好多次之後終於將ai俄羅斯方塊實現了。所謂讓機器自己去玩俄羅斯方塊,就是讓...
俄羅斯方塊
俄羅斯方塊 tetris,俄文 是一款風靡全球的電視遊戲機 和掌上遊戲機遊戲,它由俄羅斯人阿列克謝 帕基特諾夫 發明,故得此名。俄羅斯方塊的基本規則是移動 旋轉和擺放遊戲自動輸出的各種方塊,使之排列成完整的一行或多行並且消除得分。由於上手簡單 老少皆宜,從而家喻戶曉,風靡世界。俄羅斯方塊的開發者是阿...
俄羅斯方塊
include include include include includeusing namespace std include include define mem a,b memset a,b,sizeof a const int sudu 40 const int dir 4 2 cons...