要noip2019普及組複賽試題

2022-01-03 06:15:39 字數 6126 閱讀 3299

1樓:匿名使用者

noip2008解題報告

一、isbn號碼

基礎字串處理題,心細一點的基本都能得滿分。

參考程式:

program isbn;

const

inp='isbn.in';

oup='isbn.out';

vari,j,k,ans:longint;

s:string;

ch:char;

procedure flink;

begin

assign(input,inp);

reset(input);

assign(output,oup);

rewrite(output);

end;

procedure fclose;

begin

close(input);

close(output);

end;

begin

flink;

readln(s);// 輸入字串

j:=0;

i:=1;

ans:=0;

while j<9 do

begin

if s[i] in ['0'..'9'] then//如果是數字,那麼累加到ans中,共9個數字

begin

inc(j);

inc(ans,(ord(s[i])-ord('0'))*j);

end;

inc(i);

end;

ans:=ans mod 11;計算識別碼

if ans=10 then ch:='x' else ch:=chr(ord('0')+ans);//把識別碼轉換成字元,方便輸出

if s[length(s)]=ch

then write('right')

else write(copy(s,1,12)+ch);//輸出正確的識別碼

fclose;

end.

二、排座椅

用的是賽前集訓時提到的貪心,當時說某些題目用貪心可以得部分分,但是本題貪心可以得滿分的。

當然本題的貪心需要預處理下,開2個一維陣列,row[i]錄如果在第i行加通道,可以分割多少對調皮學生,col[i]記錄如果在第j列加通道,可以分割多少對調皮學生,最後貪心法輸出分割學生最多的前k行和前l列。

參考程式:

program seat;

const

inp='seat.in';

oup='seat.out';

varflag,m,n,k,l,d,i,j,x,y,x1,y1:longint;

tmp,col,row:array[1..1000] of longint;

s,s1:ansistring;

procedure flink;

begin

assign(input,inp);

reset(input);

assign(output,oup);

rewrite(output);

end;

procedure fclose;

begin

close(input);

close(output);

end;

function min(a,b:longint):longint;

begin

if a

end;

procedure qsort(m,n:longint);//快排

vari,j,k,t:longint;

begin

i:=m; j:=n; k:=tmp[(i+j) shr 1];

repeat

while tmp[i]>k do inc(i);

while tmp[j]j;

if m0 then

begin

inc(j);

tmp[j]:=row[i];

end;

end;

qsort(1,j);//對tmp陣列排序

flag:=tmp[k];//flag為前k項的最小值

i:=1; j:=0;

while (i<=n) and (j=flag then //如果該行能分割的人數不少於flag,說明此處可以新增通道

begin

write(i);

inc(j);

if j<>k then write(' ');

end;

inc(i);

end;

writeln;

//下面是求列通道,思想同上

j:=0;

for i:= 1 to n do

begin

if col[i]>0 then

begin

inc(j);

tmp[j]:=col[i];

end;

end;

qsort(1,j);

flag:=tmp[l];

i:=1; j:=0;

while (i<=m) and (j=flag then

begin

write(i);

inc(j);

if j<>l then write(' ');

end;

inc(i);

end;

fclose;

end.

三、傳球遊戲

直接dp,似乎說遞推更確切點。

f(i,k)表示經過k次傳到編號為i的人手中的方案數。那麼可以推出下面的方程:

f(i,k)=f(i-1,k-1)+f(i+1,k-1) (i=1或n時,需單獨處理)

邊界條件:f(1,0)=1;

結果在f(1,m)中

參考程式:

program ball;

const

inp='ball.in';

oup='ball.out';

vari,j,k,n,m:longint;

f:array[0..30,0..30] of longint;

procedure flink;

begin

assign(input,inp);

reset(input);

assign(output,oup);

rewrite(output);

end;

procedure fclose;

begin

close(input);

close(output);

end;

begin

flink;

readln(n,m);

fillchar(f,sizeof(f),0);

f[1,0]:=1;

for k:=1 to m do//注意此處2個迴圈的次序

begin

f[1,k]:=f[2,k-1]+f[n,k-1];

for i:= 2 to n-1 do

f[i,k]:=f[i-1,k-1]+f[i+1,k-1];

f[n,k]:=f[n-1,k-1]+f[1,k-1];

end;

write(f[1,m]);

fclose;

end.

四、立體圖

pku原題,編號2330

算不上難題,但是比較麻煩,細心點就ok了。

先計算好畫布的大小,再寫一個根據左下角座標繪製一個單位立方體的子程式。

然後遵循下面法則,不停繪製若干個立方體。(此處能體現出分割程式的偉大)

因為要不停的覆蓋,所以要遵循「視覺法則」:

1. 先繪里層再繪外層

2. 先繪底層再繪上層

3. 先回左邊再繪右邊

參考程式:

program drawing;

const

inp='drawing.in';

oup='drawing.out';

varm,n,i,j,k,x,y,h,tmp,maxx,maxy:longint;

map:array[1..1000,1..1000] of char;//畫布

a:array[1..50,1..50] of integer;//記錄輸入的矩陣

procedure flink;

begin

assign(input,inp);

reset(input);

assign(output,oup);

rewrite(output);

end;

procedure fclose;

begin

close(input);

close(output);

end;

procedure print;//輸出畫布

vari,j:longint;

begin

for i:= 1 to maxx do

begin

for j:= 1 to maxy do

write(map[i,j]);

if i<>maxx then writeln;

end;

end;

procedure draw(x,y:longint);//在畫布(map陣列)上繪製左下角座標為(x,y)的一個單位立方體

begin

map[x,y]:='+';map[x,y+1]:='-'; map[x,y+2]:='-';map[x,y+3]:='-';map[x,y+4]:='+';

dec(x);

map[x,y]:='|';map[x,y+1]:=' '; map[x,y+2]:=' ';map[x,y+3]:=' ';map[x,y+4]:='|';

map[x,y+5]:='/';

dec(x);

map[x,y]:='|';map[x,y+1]:=' '; map[x,y+2]:=' ';map[x,y+3]:=' ';map[x,y+4]:='|';

map[x,y+5]:=' ';map[x,y+6]:='+';

dec(x);

map[x,y]:='+';map[x,y+1]:='-'; map[x,y+2]:='-';map[x,y+3]:='-';map[x,y+4]:='+';

map[x,y+5]:=' ';map[x,y+6]:='|';

dec(x); inc(y);

map[x,y]:='/';map[x,y+1]:=' '; map[x,y+2]:=' ';map[x,y+3]:=' ';map[x,y+4]:='/';

map[x,y+5]:='|';

dec(x);inc(y);

map[x,y]:='+';map[x,y+1]:='-'; map[x,y+2]:='-';map[x,y+3]:='-';map[x,y+4]:='+';

end;

begin

flink;

for i:= 1 to 1000 do

for j:= 1 to 1000 do

map[i,j]:='.'; //初始化畫布

readln(m,n);

//計算畫布大小maxx * maxy

maxy:=n*4+1+m*2;

maxx:=0;

for i:= 1 to m do

begin

tmp:=0;

for j:= 1 to n do

begin

read(a[i,j]);

if a[i,j]>tmp then tmp:=a[i,j];

end;

tmp:=tmp*3+3+(m-i)*2;

if tmp >maxx then maxx:=tmp;

readln;

end;

//開始往畫布上繪圖

for i:= 1 to m do

for j:= 1 to n do

begin

x:=maxx-(m-i)*2;//第i層第j列最下方立方體左下角點的位置(x,y)

y:=(m-i)*2+(j-1)*4+1;

for k:= 1 to a[i,j] do

draw(x-(k-1)*3,y);//繪製每層的若干個一個單位立方體

end;

print;//輸出畫布

fclose;

end.

NOIP2019普及組複賽第4題文化之旅

滿分搜尋的話,按理用下面幾個剪枝就可以了.1 最優性剪枝 ans nowdist mindist nowdist當前走過的路程,mindist至少還要走多遠 2 刪去所有影響終點的城市 不可能走到的 3 倒搜 說實話給 pj 組的寫 std 時是這麼寫的 ac過了.雖然怎麼說倒搜似乎有些說不過.另把...

2019NOIP複賽怎麼複習,2017NOIP複賽怎麼複習?

第一題考的是模擬,就是按著他的思路下來,也不用什麼很難的數學思維就行。看一下去年的第一個笨小猴,就是那個難度的,一般比較水。能拿下來那個題,就100了。如果簡單,第二個是稍微花一點心思的題,一般也不會很難。數學思維幾乎用不到。再加上後面兩個騙一點分,再加個10分問題不大。應該就沒什麼問題了。這樣三等...

5G手機已經開始要普及,現在買4G划算嗎?

個人覺得現在屬於5g試執行階段,要想全民普及並使用還需要一段時間,現在買4g真的是可以的,也比較便宜一些。還是買5g手機吧,畢竟5g時代快來了,買了4g到時候沒法用,但是5g現在也可以用4g的網路,5g普及以後也不用再換手機了。現在的5g手機已經開始普及,很多的4g手機在慢慢被淘汰,所以買4g手機不...