四個數列(二分法)

2021-10-03 21:21:05 字數 1706 閱讀 4406

一、題目描述

zjm 有四個數列 a,b,c,d,每個數列都有 n 個數字。zjm 從每個數列中各取出乙個數,他想知道有多少種方案使得 4 個數的和為 0。

當乙個數列中有多個相同的數字的時候,把它們當做不同的數對待。

請你幫幫他吧!

input

第一行:n(代表數列中數字的個數) (1≤n≤4000)

接下來的 n 行中,第 i 行有四個數字,分別表示數列 a,b,c,d 中的第 i 個數字(數字不超過 2 的 28 次方)這裡是引用

output

輸出不同組合的個數。

sample input

6-45 22 42 -16

-41 -27 56 30

-36 53 -37 77

-36 30 -75 -46

26 -38 -10 62

-32 -54 -6 45

sample output

5

hint

樣例解釋: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46),(-32, 30, -75, 77), (-32, -54, 56, 30).

二、思路概述

1.考慮到如果列舉四個數列中的元素,計算每一次的和,再看共有多少個和是0,但是這種暴力列舉的方法複雜度太高,必須要找到乙個複雜度比較低的方法。

2.將a、b陣列中的元素的和列舉出來,放在乙個陣列ab裡,c、d的放在另乙個陣列cd裡,並將陣列cd進行排序。

3.然後遍歷陣列ab,每次在陣列cd中查詢ab元素的相反數有幾個。最後查詢出來的相反數的數量和就是我們要求的答案。

三、注意點(錯過的地方)

1.我計算ab中元素的相反數個數的方法是:對陣列cd進行二分查詢,找到相反數出現的最後乙個位置,和出現的第乙個位置,他們的差+1,就是相反數的個數。而最初的我沒有加上這個1,就出錯了。

四、新的函式用法

1.二分法是一種非常有效且快速的查詢方法,可以應用於很多的地方,但是使用的時候要靈活應用。

五、完整**

#include

#include

using

namespace std;

int n;

intfind1

(int x,

int*cd)

//找到x在陣列的第乙個位置

else

if(cd[mid]

>x)r=mid-1;

else l=mid+1;

}return ans;

}int

find2

(int x,

int*cd)

//找到x在陣列的最後乙個位置

else

if(cd[mid]

>x)r=mid-1;

else l=mid+1;

}return ans;

}void

csum

(int

*ab,

int*cd)

} cout<}int

main()

二分 四個數列

zjm 有四個數列 a,b,c,d,每個數列都有 n 個數字。zjm 從每個數列中各取出乙個數,他想知道有多少種方案使得 4 個數的和為 0。當乙個數列中有多個相同的數字的時候,把它們當做不同的數對待。請你幫幫他吧!第一行 n 代表數列中數字的個數,1 n 4000 接下來的 n 行中,第 i 行有...

B 4個數列 二分法

zjm 有四個數列 a,b,c,d,每個數列都有 n 個數字。zjm 從每個數列中各取出乙個數,他想知道有多少種方案使得 4 個數的和為 0。對於四個數列之和,最暴力的想法就是列舉四個數列的數,那樣時間複雜度是o n 4 顯然複雜度太高了。我們的思路是,計算a b的和 o n n 存放在陣列a裡面 ...

四個數列(二分求解)

小明有四個數列 a,b,c,d,每個數列都有 n 個數字。小明從每個數列中各取出乙個數,他想知道有多少種方案使得 4 個數的和為 0。ps 當乙個數列中有多個相同的數字的時候,把它們當做不同的數對待。input 第一行 n 代表數列中數字的個數 1 n 4000 接下來的 n 行中,第 i 行有四個...