【 UVA - 1152 】4 Values whose Sum is 0 (和为0的4个值) 中途相遇法 + 二分查找

题目传送

思路:

将a,b,c,d 分为a+b-c-d,然后通过二分查找,对比二者是否相等,若相等则满足 a+b+c+d=0

为了解决二分查找中有重复的值,可以使用upper_bound(第一个大于)和lower_bound(第一个大于等于)分别找一次,然后取差就行。


代码:

在这里插入图片描述

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue> 
#include <set>
#include <map>
using namespace std;
typedef long long ll;
const int maxn=4010*4010; //n最大4010,a+b或c+d的情况最多有n*n种
int main()
{
	int t,n,flag=0;
	cin>>t;
	while(t--)
	{
		if(!flag) flag=1;
		else cout<<endl;
		cin>>n;
		ll a[maxn],b[maxn],c[maxn],d[maxn],x[maxn],y[maxn],cnt=0,ans=0;
		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 j=0;j<n;j++)
		  {
		  	 x[cnt]=a[i]+b[j];  //a+b存入数组x
		  	 y[cnt++]=-c[i]-d[j]; //c+d存入数组y
		  }
		    
		sort(x,x+cnt); //x 和 y都排序
		sort(y,y+cnt);
		
		for(int i=0;i<cnt;i++)
		{
			int l=lower_bound(y,y+cnt,x[i])-y; //第一个大于等于x[i]的值
			int r=upper_bound(y,y+cnt,x[i])-y; //第一个大于x[i]的值
			ans+=r-l; 
		}
		    
		cout<<ans<<endl;
	}	
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值