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

时间:2023-03-09 16:44:21
对于给定的整数集合S,求出最大的d,使得a+b+c=d。

对于给定的整数集合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;
}