原題:
http://172.16.0.132/senior/#contest/show/1929/0
題目描述:
小A一直認爲,如果在一個由N個整數組成的數列An中,存在Am + An + Ap = Ai(1 <= m, n, p < i)(m, n, p可以相同)的話,Ai就是一個“好元素”。現在,小A有一個數列,他想知道這個數列中有多少個“好元素”,請你幫幫他。
輸入:
第一行只有一個正整數N,意義如上。
第二行包含N個整數,表示數列An。
輸出:
輸出一個整數,表示這個數列中“好元素”的個數。
樣例輸入:
輸入1:
2
1 3
輸入2:
6
1 2 3 5 7 10
輸入3:
3
-1 2 0
樣例輸出:
輸出1:
1
輸出2:
4
輸出3:
1
數據範圍限制:
對於10%的數據 1<=N<=10
對於40%的數據 1<=N<=500 -10^5<=Ai<=10^5
對於70%的數據 1<=N<=5000 -10^6<=Ai<=10^6
對於100%的數據 1<=N<=5000 -10^9<=Ai<=10^9
分析:
好元素
10% n^4 隨便做。
40% n^3 用布爾數組保存存在的元素,用三層枚舉a[i],a[j],a[k],如果a[i]+a[j]+a[k]存在,那麼答案加1。注意枚舉順序和判重。
70% n^2 預處理兩個數的和,再枚舉,因爲每一個元素值比較小,開一個數組來存儲是否存在。(其實n^3的方法加上剪枝也可以過)
100% n^2 因爲元素的值比較大,在70%的思想上用哈希進行判斷即可。
實現:
const
id=14150547;
var
i,j,t,n,ans,k:longint;
bz:boolean;
sum:array[-id..id] of longint;
a:array[0..5001] of longint;
function hash(i:longint):longint;
var
j:longint;
begin
j:=i mod id;
while(sum[j]<>0)and(sum[j]<>i)do j:=(j+1) mod id;
exit(j);
end;
begin
assign(input,'good.in');reset(input);
assign(output,'good.out');rewrite(output);
readln(n);
for i:=1 to n do
begin
read(a[i]);
for j:=1 to i-1 do
begin
t:=a[i]-a[j];
if t=0 then
begin
if bz then
begin
inc(ans);
break;
end;
end
else
if sum[hash(t)]=t then
begin
inc(ans);
break;
end;
end;
if a[i]=0 then bz:=true;
for j:=1 to i do
sum[hash(a[i]+a[j])]:=a[i]+a[j];
end;
writeln(ans);
close(input);close(output);
end.