ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

SDU程序设计思维与实践 week4 B - 四个数列 (二分)

2020-03-13 22:02:26  阅读:272  来源: 互联网

标签:SDU 数列 int back mid ans push week4


题目描述

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

输入描述

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

输出描述

输出不同组合的个数。

输入样例

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

输出样例

5

思路分析

1、采用四重循环遍历四个数组的方法复杂度O(N4N^4N4),无法接受
2、采用分而治之的思想。分别枚举AB和CD。

  • 枚举A+B的和
  • 对A+B的和排序
  • 枚举C+D、计算它的相反数在A+B中出现多少次,计算的方法为二分查找相反数在A+B中第一次出现的位置和最后一次出现的位置

代码

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int n;
vector<int> a,b,c,d,ab,cd;
//返回第一个等于x的位置 
int findl(int x){
	int l=0,r=ab.size()-1,ans=-1;
	while(l<=r){
		int mid=(l+r)/2;
		if(ab[mid]==x){
			ans=mid;
			r=mid-1;
		}
		else if(ab[mid]>x) r=mid-1;
		else l=mid+1;
	}
	return ans;
}
//返回最后一个等于x的位置 
int findr(int x){
	int l=0,r=ab.size()-1,ans=-1;
	while(l<=r){
		int mid=(l+r)/2;
		if(ab[mid]==x){
			ans=mid;
			l=mid+1;
		}
		else if(ab[mid]>x) r=mid-1;
		else l=mid+1;
	}
	return ans;
}



int main(){
	cin>>n;
	int ans=0; 
	for(int i=0;i<n;i++){
		int t1,t2,t3,t4;
		cin>>t1>>t2>>t3>>t4;
		a.push_back(t1);b.push_back(t2);c.push_back(t3);d.push_back(t4);
		
	}

	//计算a+b; 
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			ab.push_back(a[i]+b[j]);
		}
	}

	sort(ab.begin(),ab.end());
	//枚举c+d
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			int temp=(c[i]+d[j])*-1;
			//寻找第一次出现的位置、最后一次出现的位置 
			int l=findl(temp),r=findr(temp);
			if(l!=-1){
			 	ans+=(r-l+1);
			}
		}
	}
	cout<<ans<<endl; 
}

标签:SDU,数列,int,back,mid,ans,push,week4
来源: https://blog.csdn.net/weixin_43975891/article/details/104850376

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有