对于给定的整数集合S,求出最大的d,使得a+b+c=d。a,b,c,d互不相同,且都属于S。集合的元素个数小于等于2000个,元素的取值范围在[-2^28,2^28 - 1],假定可用内存空间为100MB,硬盘使用空间无限大,试分析时间和空间复杂度,找出最快的解决方法。

提示:两两相加转为多项式乘法,比如(1 2 4 6) + (2 3 4 5) => (x + x^2 + x^4 + x^6)*(x^2 + x^3 + x^4 + x^5) 。

#include <iostream>
#include<map>
#include "bitmap.h"
using namespace std;

#define M (1024*1024*512)
#define N 2000

multimap<int, int> mmp;

void printBitmap(int n) {
	for (int i = 0; i < n; ++i) {
		if (test(i)) {
			cout << i << ' ';
		}
	}
	cout << endl;
}

void printMutimap() {
	multimap<int, int>::iterator i, iend;
	iend = mmp.end();
	for (i = mmp.begin(); i != iend; i++) {
		cout << (*i).first << ' ' << (*i).second << endl;
	}
}

int* initRandom(int len, int range) {
	int* randoms = new int[len];
	srand(unsigned(time(0)));
	for (int i = 0; i < len; i++) {
		randoms[i] = rand() % range;
	}
	return randoms;
}

void printArray(int* arr, int len) {
	cout << "数组:" << endl;
	for (int i = 0; i < len; ++i) {
		cout << arr[i] << ' ';
	}
	cout << endl;
}

/*求出集合中每2个数的和,并用bitmap存储,
 * multimap里边的key为2个数的和,value值为较小的数,则另一个值为key-value*/
void enumSum(int*arr, int len) {
	for (int i = 1; i < len; ++i) {
		if (arr[i - 1] != arr[i])
			for (int j = i; j < len; ++j) {
				//arr[i - 1] != arr[j]和的2个数必须不同
				if (arr[j - 1] != arr[j] && arr[i - 1] != arr[j]) {
					int sum = arr[i - 1] + arr[j];
//					set(sum);
					mmp.insert(make_pair(sum, arr[i - 1]));
				}
			}
	}
}

int* enumSub(int* arr, int len) {
	typedef multimap<int, int>::size_type sz_type;

	for (int i = len - 1; i >= 0; --i) {
		for (int j = i - 1; j >= 0; --j) {
			if (arr[i] != arr[j]) {
				int sub = arr[i] - arr[j];
//				if (test(sub)) {
					sz_type entries = mmp.count(sub);
					if (entries == 0) {
						continue;
					} else {
						multimap<int, int>::iterator iter = mmp.find(sub);
						for (sz_type cnt = 0; cnt != entries; ++cnt, ++iter) {
							if (iter->second == arr[i]
									|| iter->second == arr[j]) {
								continue;
							} else if (iter->first - iter->second == arr[i]
									|| iter->first - iter->second == arr[j]) {
								continue;
							}
							/*M区间[-2^28,2^28 - 1],所以正式结果必须减去(2^28-1)*/
							int* result = new int[4];
							result[0] = iter->first - iter->second;
							result[1] = iter->second;
							result[2] = arr[j];
							result[3] = arr[i];
							return result;
						}
					}
//				}
			}
		}
	}
	return NULL;
}

int main() {
	bitmap = new int[M / 32]; //M / 32
	memset(bitmap, 0, M / 32 * sizeof(int)); //M * sizeof(int)

	int* arr = initRandom(N, M);
	sort(arr, arr + N);
//	printArray(arr, N);

	clock_t start_time = clock();

	enumSum(arr, N);
	/*printBitmap(N);
	 printMutimap();
	 */
//	enumSub(arr, N);
	int* result = enumSub(arr, N);
	if (result) {
		cout << result[0] << '+' << result[1] << '+' << result[2] << '='
				<< result[3] << endl;
	}

	clock_t end_time = clock();
	cout << "Running time is: "
			<< static_cast<double>(end_time - start_time) / CLOCKS_PER_SEC
					* 1000 << "ms" << endl; //输出运行时间

	return 0;
}

对于给定的整数集合S,求出最大的d,使得a+b+c=d。的更多相关文章

  1. 已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2)位的整数,则求出w的后n-1位的数。

    描述 已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2)位的整数,则求出w的后n-1位的数.   输入 第一行为M,表示测试数据组数.接下来M行,每行包含一个测试数据. 输出 ...

  2. 2018.3.12 Leecode习题 给定一个整数数列,找出其中和为特定值的那两个数。

    给定一个整数数列,找出其中和为特定值的那两个数. 你可以假设每个输入都只会有一种答案,同样的元素不能被重用. 示例: 给定 nums = [2, 7, 11, 15], target = 9; 因为 ...

  3. 作业帮:给定一个整数数组,找出其中两个数相加等于目标值(去重set)

    题目描述 给定一个整数数组,找出其中两个数相加等于目标值 输入 [1,3,5,7,9,11] 10 输出 1,9 3,7 代码: import java.util.HashMap; import ja ...

  4. 给定一个整数N,找出一个比N大且最接近N,但二进制权值与该整数相同 的数

    1,问题描述 给定一个整数N,该整数的二进制权值定义如下:将该整数N转化成二进制表示法,其中 1 的个数即为它的二进制权值. 比如:十进制数1717 的二进制表示为:0000 0110 1011 01 ...

  5. codevs:1462 素数和:给定2个整数a,b 求出它们之间(不含a,b)所有质数的和。

    #include<iostream>#include<cstdio>#include<cmath>using namespace std;int main(){ i ...

  6. 编写一个应用程序,利用数组或者集合, 求出"HELLO",“JAVA”,“PROGRAM”,“EXCEPTION”四个字符串的平均长度以及字符出现重复次数最多的字符串。

    public class Number { public static void main(String[] args) { String[] arr = { "HELLO", & ...

  7. 如何求出数组中最小(或者最大)的k个数(least k问题)

    输入n个整数,如何求出其中最小的k个数? 解法1. 当然最直观的思路是将数组排序,然后就可以找出其中最小的k个数了,时间复杂度以快速排序为例,是O(nlogn): 解法2. 借助划分(Partitio ...

  8. C语言:找出一个大于给定整数m且紧随m的素数,-求出能整除x且不是偶数的数的个数,

    //函数fun功能:找出一个大于给定整数m且紧随m的素数,并作为函数值返回. #include <stdlib.h> #include <conio.h> #include & ...

  9. 设计算法,求AB两个整数集合的交集

    [本文链接] http://www.cnblogs.com/hellogiser/p/ab-set-intersection.html [分析] 思路1:排序法 对集合A和集合B进行排序(升序,用快排 ...

随机推荐

  1. [LeetCode] Decode Ways II 解码方法之二

    A message containing letters from A-Z is being encoded to numbers using the following mapping way: ' ...

  2. 二 Djano模型层之模型字段选项

    字段选项 以下参数是全部字段类型都可用的,而且是可选的 null 如果为True,Django将在数据库中将空值存储为NULL.默认值为False 对于字符串字段,如果设置了null=True意味着& ...

  3. [ Java学习基础 ] Java的封装性与访问控制

    Java面向对象的封装性是通过对成员变量和方法进行访问控制实现的,访问控制分为4个等级:私有.默认.保护和公有,具体规则如下表: 1.私有级别 私有级别的关键字是private,私有级别的成员变量和方 ...

  4. ●BZOJ 1096 [ZJOI2007]仓库建设

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1096 题解: 斜率优化DP $(d_i:i 位置到1位置的距离,p_i:i位置的成品数量,c ...

  5. JVM学习记录-对象已死吗

    前言 先来回顾一下,在jvm运行时数据区,分为两部分,一个部分是线程共享区,主要包括堆和方法区,另一部是线程私有区分包括本地方法栈,虚拟机栈和程序计数器.在线程私有部分的三个区域是随着线程生和灭的.栈 ...

  6. Go实现海量日志收集系统(三)

    再次整理了一下这个日志收集系统的框,如下图 这次要实现的代码的整体逻辑为: 完整代码地址为: https://github.com/pythonsite/logagent etcd介绍 高可用的分布式 ...

  7. java中什么是序列化和反序列化

    序列化:能够把一个对象用二进制的表示出来. 类似我第一个字节表示什么属性名词,第二个字节表示什么属性值,第几个字段表示有几个属性等. 而且这个二进制可以写到硬盘或者在网络上传输但不会破坏他的结构.一般 ...

  8. map内置函数、lambda表达式、快捷生成想要的列表、filter内置函数

      map函数                             语法 map(function, iterable, ...) 参数 function -- 函数,有两个参数 iterable ...

  9. CSS3左右间歇晃动效果

    今天在做一个活动页面时,产品想要在页面中添加一个吸引人注意的小图片左右晃动的效果,并且该效果是间歇执行的.我一想应该挺简单的吧,二话没说就答应了,谁知在真正实现的时候才发现还是有些许困难的.于是就在网 ...

  10. JSON.parse()在火狐中的BUG

      //用sessionStorage解决load页面刷新问题 { //sessionStorage.removeItem("loadInfo"); var loadInfo=de ...