其實呢,這道題大部分是思路,對於資訊學的**啊、演算法啊,並沒有特別高的要求。
看到題目資料,便大吃一驚:資料裡的水分呢???暴搜和水法肯定是不能ac的了。不過,「資料就像海綿,只要擠,總是有水的。」事實證明,「水法真神奇,暴力出奇蹟」同樣適用於這道題目。4重迴圈,時間o(n4)也是可以水到過半的分的。然而,頓時又通過b-a=2(d-c)這個等式,可以在已知a,b,c的情況下直接求出d。時間o(n
3),拿到75分不是問題。接著,通過b-ab*4-3*a等取值範圍,這樣可以拿到80~85分。
接著,正解:
通過b-a0):
2i >6i(6i+k) i
___|______|___________________|___|___
a b c d
(a) (a+2i) (a+8i+k) (a+9i+k)
這時候,就可以依次列舉i,a,k三個數以得出結果,時間o((n div 9)*(n-9i-1)*(n-i*9)。然並卵,這樣還是會超時。所以可以加點優化。
不難發現,每一次列舉i中會重複多次求可能的,k的方案數,而c,d就是目標(a+8i+k和a+9i+k),所以,我們可以在每一次列舉i的起始位置,先求出c的取值範圍在i~j之間的c,d取法數。然而這樣會爆空間,所以,我們就用w[i]表示c的取值範圍在i~n之間的c,d取法數。則w[i]-w[j+1]表示c的取值範圍在i~j之間的c,d取法數。而w陣列就是字尾和,再用相對的方法將s陣列中存a的字首和。
當你完成這一切時,你就可以利用前字尾和將程式活生生壓成for i中四個for j的四重迴圈了打上輸入輸出,ac和同學們在前方等著你!!!
var
a,b,c,d,n,m,i,j:longint;
s:array [1..15000,1..4] of longint;//答案
bj:array [1..15000] of longint;//每個數出現的次數
t:array [1..40000] of longint;//儲存輸入的n個數
begin
assign(input,'magic.in'); reset(input);
assign(output,'magic.out'); rewrite(output);
readln(n,m); n:=0;
for i:=1
to m do
begin
readln(t[i]);
inc(bj[t[i]]);
if t[i]>n then n:=t[i];
end;//輸入
for a:=1
to n do
if bj[a]>0
then
begin
b:=a+2;
while b<=n do
begin
if bj[b]>0
then
begin
for c:=4*b-3*a+1
to n do //由公式得出
if bj[c]>0
then
begin
d:=c+(b-a) div
2;//三重迴圈列舉
if bj[d]>0
then
begin
inc(s[a,1],bj[b]*bj[c]*bj[d]);
inc(s[b,2],bj[a]*bj[c]*bj[d]);
inc(s[c,3],bj[a]*bj[b]*bj[d]);
inc(s[d,4],bj[a]*bj[b]*bj[c]);//更新答案
end;
end;
end;
inc(b,2);
end;
end;
for i:=1
to m do
begin
for j:=1to4
dobegin
write(s[t[i],j],' ');
end;
writeln;
end;//輸出
close(input); close(output);
end.
NOIP2016普及組第四題 魔法陣
題目描述 六十年一次的魔法戰爭就要開始了,大魔法師準備從附近的魔法場中汲取魔法能量。大魔法師有m個魔法物品,編號分別為1,2,m。每個物品具有乙個魔法值,我們用xi表示編號為i的物品的魔法值。每個魔法值xi是不超過n的正整數,可能有多個物品的魔法值相同。大魔法師認為,當且僅當四個編號為a,b,c,d...
NOIP 2016 普及組 海港
題目鏈結 小k是乙個海港的海關工作人員,每天都有許多船隻到達海港,船上通常有很多來自不同國家的乘客。小k對這些到達海港的船隻非常感興趣,他按照時間記錄下了到達海港的每一艘船隻情況 對於第i艘到達的船,他記錄了這艘船到達的時間ti 單位 秒 船上的乘客數ki,以及每名乘客的國籍 xi,1,xi,2,x...
noip2016普及組複賽總結
9點半從紀中出發,大概11點多來到廣州六中。在六中旁邊一家小餐館吃了中餐,那餐廳真心很貴,一盆飯就要20元,我們那桌吃了四 盆.xc 不想買單啦 啦啦啦 然後就來到六中的某個功能室百無聊賴的休息了一會兒,兩點鐘進考場。兩點半 比賽開始,還是先看題.一二兩題太水了,直接開碼,1小時搞定兩題 三點半 仔...