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手機不...