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