首页 > 代码库 > POJ2549 Sumsets 折半枚举
POJ2549 Sumsets 折半枚举
题目大意是,一个集合中有N个元素,找出最大的S,满足条件A+B+C=S,并且这四个数都属于该集合,N不超过1000.
如果直接枚举O(n^4)显然复杂度太高,将等式转化一下A+B=S-C,此时分别对左右两边的值进行枚举,这一步复杂度为O(n ^ 2),接着就用二分法查找满足该等式的最大S值,
复杂度为O(n^2*log(n))。
#include <stdio.h> #include <vector> #include <math.h> #include <string.h> #include <string> #include <iostream> #include <queue> #include <list> #include <algorithm> #include <stack> #include <map> using namespace std; int values[1001]; struct MyStruct { int i; int j; int res; }; int compp(const void* a1, const void* a2) { return *(int*)a1 - *(int*)a2; } int compp1(const void* a1, const void* a2) { return ((MyStruct*)a1)->res - ((MyStruct*)a2)->res; } MyStruct S[2][1000000]; int main() { #ifdef _DEBUG freopen("e:\\in.txt", "r", stdin); #endif int n; while (scanf("%d", &n) != EOF) { if (n == 0) { break; } for (int i = 0; i < n; i++) { scanf("%d", &values[i]); } qsort(values, n, sizeof(int), compp); int count = 0; for (int i = n - 1; i >= 0; i--) { for (int j = i - 1; j >= 0; j--) { S[0][count].i = i; S[0][count].j = j; S[0][count].res = values[i] - values[j]; count++; } } count = 0; for (int i = n - 1; i >= 0; i--) { for (int j = i - 1; j >= 0; j--) { S[1][count].i = i; S[1][count].j = j; S[1][count].res = values[i] + values[j]; count++; } } qsort(S[1], count, sizeof(MyStruct), compp1); bool ans = false; for (int i = 0; i < count;i++) { if (ans) { break; } int l = 0; int r = count; while (r - l > 1) { int mid = (l + r) / 2; if (S[0][i].res <= S[1][mid].res) { r = mid; } else l = mid; } for (int j = l; j < count;j++) { if (S[0][i].res < S[1][j].res) { break; } if (S[0][i].i == S[1][j].i || S[0][i].i == S[1][j].j|| S[0][i].j == S[1][j].i || S[0][i].j == S[1][j].j) { continue; } if (S[0][i].res == S[1][j].res) { ans = true; printf("%d\n", values[S[0][i].i]); break; } } } if (!ans) { printf("no solution\n"); } } return 1; }
POJ2549 Sumsets 折半枚举
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。