程式設計Week4 B 四個數列

2021-10-04 03:51:22 字數 1257 閱讀 6156

四個數列a、b、c、d,每個數列n個數字,從四個數列中各取乙個數,求共有多少種方案使得4個數和為0。當乙個數列中有多個相同的數字的時候,把它們當做不同的數對待。

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

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

輸出不同組合的個數。

暴力列舉必然不可取,n<=4000的四重迴圈必然超時,考慮o(n^2)的複雜度演算法,因為a+b+c+d=0相當於a+b=-(c+d),可以使用二分。

首先列舉ab數列的所有和,再列舉cd數列的和,在列舉cd和時,通過二分找到其相反數在ab數列和中第一次出現和最後一次出現的位置,由此可以統計出每組a+b=-(c+d)個個數,最後輸出總個數即可。

#include

#include

using

namespace std;

int a[

4010

],b[

4010

],c[

4010

],d[

4010];

int ab_sum[

16000010];

intfind_first

(int x,

int l,

int r)

else

if(x>ab_sum[mid]

) l=mid+1;

else

r=mid-1;

}return ans;

}int

find_last

(int x,

int l,

int r)

else

if(x>ab_sum[mid]

) l=mid+1;

else

r=mid-1;

}return ans;

}int

main()

}sort

(ab_sum,ab_sum+m+1)

;for

(int i=

0;i++i)

} cout

}

本題是一道二分的題目,利用二分可以找到一組數中第乙個(最後乙個)比給定數字大或小的數,利用這種形式,我們可以很方便的找到滿足某種條件的數字或表示式的個數,帶入到本題當中,常規的四重迴圈o(n^4)複雜度顯然是不能接受的,而簡單變換形式之後,就可以使用二分的思想進行求解,大大優化了程式執行的時間。

week4 B 四個數列

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

week4 B 四個數列

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

Week4 B 四個數列

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