俄羅斯方塊 tetris

2021-06-04 10:26:00 字數 3745 閱讀 6814

俄羅斯方塊 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...