week4 作业B 四个数列

四个数列

题目:
ZJM 有四个数列 A,B,C,D,每个数列都有 n 个数字。ZJM 从每个数列中各取出一个数,他想知道有多少种方案使得 4 个数的和为 0。
当一个数列中有多个相同的数字的时候,把它们当做不同的数对待。
请你帮帮他吧!

Input:

第一行:n(代表数列中数字的个数) (1≤n≤4000)
接下来的 n 行中,第 i 行有四个数字,分别表示数列 A,B,C,D 中的第 i 个数字(数字不超过 2 的 28 次方)

Output:

输出不同组合的个数。

Example:

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
Output:
5

Hint:

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

我的解题思路:
根据题意,要求我们对于四个数列,从每个数列中选一个数,四个数加在一起,和为0。如果遍历四个数组,则复杂度太高,所以可以两两计算。计算A+B的值,然后在计算C+D的值的过程中,找在A+B值中的相反数个数,最后统计所有的要求数对个数,即可。

我的总结:
要时刻考虑复杂度。
我的代码:

#include<iostream>
#include<algorithm>
using namespace std;

long long A[4000],B[4000],C[4000],D[4000],ans,N,ANS[16000000],ind=0,temp;

int bifind(int num)
{
	int l=0,r=ind-1,ans1=-1,ans2=-1;
	while(l<=r)
	{
		int mid=(l+r)>>1;
		if(ANS[mid]==num)
		{
			ans1=mid;
			l=mid+1;
		}
		else if(ANS[mid]>num) r=mid-1;
		else l=mid+1;
	}
	l=0,r=ind-1;
	while(l<=r)
	{
		int mid=(l+r)>>1;
		if(ANS[mid]>=num)
		{
			ans2=mid;
			r=mid-1;
		}
		else l=mid+1;
	}
	if(ans1==-1||ans2==-1) return 0;
	else return ans1-ans2+1;
}

int main()
{
    cin>>N;
    for (int i=0;i<N;i++)
    {
        cin>>A[i]>>B[i]>>C[i]>>D[i];
    }
    for(int i=0;i<N;i++)
    {
    	for (int k=0;k<N;k++)
    	{
    		ANS[ind++]=A[i]+B[k];
		}
	}
	sort(ANS,ANS+ind);
	for (int i=0;i<N;i++)
	{
		for (int k=0;k<N;k++)
		{
			temp=C[i]+D[k];
			ans+=bifind(-temp);
		}
	}
	cout<<ans;
	return 0;
}
发布了26 篇原创文章 · 获赞 0 · 访问量 447

猜你喜欢

转载自blog.csdn.net/qq_43738677/article/details/104886442
今日推荐