UVALive 3506 4 Values whose Sum is 0 (二分查找)

The SUMproblem can be formulated as follows: given four lists A;B;C;D of integer values, compute

how manyquadruplet (a; b; c; d) 2 A_B _C _D are such that a+b+c+d = 0. In thefollowing, we

assume thatall lists have the same size n.

Input

The inputbegins with a single positive integer on a line by itself indicating the numberof the cases

following,each of them as described below. This line is followed by a blank line, andthere is also a

blank linebetween two consecutive inputs.

The _rstline of the input _le contains the size of the lists n (this value can be as large as 4000).

We then haven lines containing four integer values (withabsolute value as large as 228) that belong

respectivelyto A;B;C and D.

Output

扫描二维码关注公众号,回复: 812735 查看本文章

For eachtest case, your program has to write the number quadruplets whose sum is zero.

The outputsof two consecutive cases will be separated by a blank line.

Sample Input

1

6

-45 22 42-16

-41 -27 5630

-36 53 -3777

-36 30 -75-46

26 -38 -1062

-32 -54 -645

Sample Output

5

Sample Explanation: Indeed,the sum of the _ve following quadruplets is zero: (-45, -27, 42, 30),

(26, 30, -10,-46), (-32, 22, 56, -46), (-32, 30, -75, 77), (-32, -54, 56, 30).

给四个序列,每个序列选一个数, 求其和为0的情况总数。

如果直接枚举每一个序列, 其复杂度为O(n^4), 按照数据规模 n<=4000,显然会超时

可以将序列两两合并, 转化为两个4000*4000的, 再枚举其中一个的所有元素x, 在另一个中用二分查找 (–x) 的个数即可

注: 查找的是 (–x) 的个数, 所以可以先找出其下标, 在往其两边找。

另外,读题千万仔细,不要问我为什么,  比如:

This line is followed by a blank line, andthere is also a

blank linebetween two consecutive inputs.

#include<bits/stdc++.h>
using namespace std;

int book[4000*4000 + 2];
int serch(int x, int l, int r){
	if(l > r) return -1;
	int q = (l+r)/2;
	if(x == book[q]) return q;
	if(x > book[q]) return serch(x, q+1, r);
	if(x < book[q]) return serch(x, l, q-1);
}
int main(){
	int T,i,j,t,ans,n;
	int a1[4002], a2[4002], a3[4002], a4[4002];
	cin>>T;
	while(T--){
		cin>>n;
		for(i=0; i<n; i++)
			cin>>a1[i]>>a2[i]>>a3[i]>>a4[i];
		t = 0;
		for(i=0; i<n; i++)
			for(j=0; j<n; j++)
				book[t++] = a1[i] + a2[j];
		sort(book, book + t);
		ans = 0;
		int tmp;
		for(i=0; i<n; i++)
			for(j=0; j<n; j++)
				if( (tmp = serch(-a3[i]-a4[j], 0, t-1) ) != -1){
					ans++;
					int h;
					for(h=1; tmp+h<t && tmp+h>=0 && book[tmp+h]==-a3[i]-a4[j]; h++);
					ans += h-1;
					for(h=1; tmp-h<t && tmp-h>=0 && book[tmp-h]==-a3[i]-a4[j]; h++);
					ans += h-1;
				}
		cout<<ans<<endl;
		if(T) cout<<endl;
	}
}

猜你喜欢

转载自blog.csdn.net/outp0st/article/details/73656870
今日推荐