数集

  题目大意:给定一些数的集合,要你求出集合中满足a+b+c=d的最大的d(每个数只能用一次)

  这题有两种解法,

  第一种就是对分,把a+b的和先求出来,然后再枚举d-c,枚举的时候输入按照降序搜索就好,一旦d满足条件就是最大的了,另外判断不重复存一下位置就好,时间复杂度0(n^2*logn)

  

  1. #include <iostream>
  2. #include <functional>
  3. #include <algorithm>
  4.  
  5. using namespace std;
  6.  
  7. typedef long long LL_INT;
  8. static LL_INT input[];
  9. static pair<LL_INT, pair<int,int>>sums[ * ];
  10.  
  11. LL_INT solve(const int, const int);
  12.  
  13. bool cmp(const pair<LL_INT, pair<int, int>>&x, const pair<LL_INT, pair<int, int>>&y)
  14. {
  15. return x.first < y.first;
  16. }
  17.  
  18. int main(void)
  19. {
  20. LL_INT ans;
  21. int num_sum, sum_comb;
  22. while (~scanf("%d", &num_sum))
  23. {
  24. if (num_sum == ) break;
  25. for (int i = ; i < num_sum; i++)
  26. scanf("%lld", &input[i]);
  27.  
  28. sort(input, input + num_sum);
  29. sum_comb = ;
  30. for (int i = ; i < num_sum; i++)
  31. for (int j = i + ; j < num_sum; j++)
  32. sums[sum_comb++] = make_pair(input[i] + input[j], make_pair(i, j));
  33.  
  34. sort(sums, sums + sum_comb);
  35. ans = solve(num_sum, sum_comb);
  36. if (ans != INT_MAX)
  37. printf("%lld\n", ans);
  38. else
  39. printf("no solution\n");
  40. }
  41. return EXIT_SUCCESS;
  42. }
  43.  
  44. LL_INT solve(const int num_sum, const int sum_comb)
  45. {
  46. int tmp[] = { , }, pos_s, pos_up;
  47. for (int i = num_sum - ; i >= ; i--)
  48. {
  49. for (int j = num_sum - ; j >= ; j--)
  50. {
  51. if (i == j) continue;
  52. pos_s = lower_bound(sums, sums + sum_comb, make_pair(input[i] - input[j], make_pair(, )),cmp) - sums;
  53. pos_up = upper_bound(sums, sums + sum_comb, make_pair(input[i] - input[j], make_pair(, )),cmp) - sums;
  54.  
  55. if (sums[pos_s].first == input[i] - input[j])
  56. {
  57. for (int k = pos_s; k < pos_up; k++)
  58. {
  59. if (sums[k].second.first != i && sums[k].second.first != j
  60. &&sums[k].second.second != i && sums[k].second.second != j)
  61. return input[i];
  62. }
  63. }
  64. }
  65. }
  66. return (LL_INT)INT_MAX;
  67. }

  

  剪枝了还是100+ms,太慢了,我不是很满意,去网上找了下果然有更快的做法

  其实像这种找固定数的题目都可以用散列来做,把a+b散列就好了,说实话好久没做散列我都忘记散列的那几条挺好用的公式了(貌似用书上那种散列方法效率更高),这里我就直接用链表法解决了

  参考http://www.cnblogs.com/CSU3901130321/p/4546190.html

  

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <functional>
  4. #define MOD 1001 * 1001
  5.  
  6. using namespace std;
  7.  
  8. static struct _set
  9. {
  10. int val, num[], next;
  11. }memmory_pool[ * ];
  12. static int Table[ * ], input[], tp;
  13.  
  14. void Hash_To_Table(const int, const int, const int);
  15. bool Search_Table(const int, const int, const int);
  16. int solve(const int);
  17.  
  18. int main(void)
  19. {
  20. int num_sum, sum_comb, ans;
  21. while (~scanf("%d", &num_sum))
  22. {
  23. if (num_sum == )break;
  24. for (int i = ; i < num_sum; i++)
  25. scanf("%d", &input[i]);
  26. sort(input, input + num_sum);
  27. sum_comb = num_sum*(num_sum - ) / ; tp = ;
  28.  
  29. fill(Table, Table + * , -);
  30. for (int i = ; i < num_sum; i++)
  31. for (int j = i + ; j < num_sum; j++)
  32. Hash_To_Table(input[i] + input[j], i, j);
  33.  
  34. ans = solve(num_sum);
  35. if (ans != INT_MAX)
  36. printf("%d\n", ans);
  37. else
  38. printf("no solution\n");
  39. }
  40. return EXIT_SUCCESS;
  41. }
  42.  
  43. void Hash_To_Table(const int _int_value, const int i, const int j)
  44. {
  45. int pos = (_int_value > ? _int_value : -_int_value) % MOD;
  46. memmory_pool[tp].val = _int_value;
  47. memmory_pool[tp].num[] = i;
  48. memmory_pool[tp].num[] = j;
  49. memmory_pool[tp].next = Table[pos];
  50. Table[pos] = tp++;
  51. }
  52.  
  53. bool Search_Table(const int _int_value, const int i, const int j)
  54. {
  55. int pos = (_int_value > ? _int_value : -_int_value) % MOD;
  56. for (int k = Table[pos]; k != -; k = memmory_pool[k].next)
  57. {
  58. if (memmory_pool[k].val == _int_value)
  59. {
  60. if (memmory_pool[k].num[] != i &&memmory_pool[k].num[] != i
  61. &&memmory_pool[k].num[] != j &&memmory_pool[k].num[] != j)
  62. return true;
  63. }
  64. }
  65. return false;
  66. }
  67.  
  68. int solve(const int num_sum)
  69. {
  70. for (int i = num_sum - ; i >= ; i--)
  71. {
  72. for (int j = num_sum - ; j >= ; j--)
  73. {
  74. if (i == j)continue;
  75. if (Search_Table(input[i] - input[j], i, j))
  76. return input[i];
  77. }
  78. }
  79. return INT_MAX;
  80. }

  

  散列法复杂度是O(N^2),非常快。

  (另外有人在讨论版说他用O(n^3*logn)的时间复杂度方法94ms做出来了,我自己试了一下,如果他储存位置下标位置是一定会溢出的,不知道他怎么做出来的,而且就算是O(N^2*logn)的算法也是要用100+ms,我对他的做法表示怀疑)。

Divide and conquer:Sumsets(POJ 2549)的更多相关文章

  1. Divide and conquer:Subset(POJ 3977)

    子序列 题目大意:给定一串数字序列,要你从中挑一定个数的数字使这些数字和绝对值最小,求出最小组合数 题目的数字最多35个,一看就是要数字枚举了,但是如果直接枚举,复杂度就是O(2^35)了,显然行不通 ...

  2. Divide and conquer:Showstopper(POJ 3484)

    Showstopper 题目大意:数据挖掘是一项很困难的事情,现在要你在一大堆数据中找出某个数重复奇数次的数(有且仅有一个),而且要你找出重复的次数. 其实我一开始是没读懂题意的...主要是我理解错o ...

  3. Divide and conquer:Garland(POJ 1759)

     挂彩灯 题目大意:就是要布场的时候需要挂彩灯,彩灯挂的高度满足: H1 = A Hi = (Hi-1 + Hi+1)/2 - 1, for all 1 < i < N HN = B Hi ...

  4. Divide and conquer:Matrix(POJ 3685)

    矩阵 题目大意:矩阵里面的元素按i*i + 100000 * i + j*j - 100000 * j + i*j填充(i是行,j是列),求最小的M个数 这一题要用到两次二分,实在是二分法的经典,主要 ...

  5. Divide and conquer:Median(POJ 3579)

        快速求两数距离的中值 题目大意:给你一个很大的数组,要你求两个数之间的距离的中值 二分法常规题,一个pos位就搞定的事情 #include <iostream> #include ...

  6. Divide and conquer:Drying(POJ 3104)

    烘干衣服 题目大意:主人公有一个烘干机,但是一次只能烘干一件衣服,每分钟失水k个单位的水量,自然烘干每分钟失水1个单位的水量(在烘干机不算自然烘干的那一个单位的水量),问你最少需要多长时间烘干衣服? ...

  7. [LeetCode] 236. Lowest Common Ancestor of a Binary Tree_ Medium tag: DFS, Divide and conquer

    Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...

  8. [LeetCode] 系统刷题4_Binary Tree & Divide and Conquer

    参考[LeetCode] questions conlusion_InOrder, PreOrder, PostOrder traversal 可以对binary tree进行遍历. 此处说明Divi ...

  9. [LeetCode] 124. Binary Tree Maximum Path Sum_ Hard tag: DFS recursive, Divide and conquer

    Given a non-empty binary tree, find the maximum path sum. For this problem, a path is defined as any ...

随机推荐

  1. Storm与Spark Streaming比较

    前言spark与hadoop的比较我就不多说了,除了对硬件的要求稍高,spark应该是完胜hadoop(Map/Reduce)的.storm与spark都可以用于流计算,但storm对应的场景是毫秒级 ...

  2. AngularJS API之bootstrap启动

    对于一般的使用者来说,AngularJS的ng-app都是手动绑定到某个dom元素.但是在一些应用中,这样就显得很不方便了. 绑定初始化 通过绑定来进行angular的初始化,会把js代码侵入到htm ...

  3. 2015多校1006.First One

    First One Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total ...

  4. 开关WIFI脚本

    title wifi管理color A@echo on@echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@echo 1.启用并设定虚拟WiFi网卡;@echo 2.开启无线网络; ...

  5. HDu1003(maxn sum)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABBcAAAMDCAYAAAD5XP0yAAAgAElEQVR4nOy97a8c133n2X+H3xjIC4

  6. js引出函数概念的案例

    js引出函数概念的案例   1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8&q ...

  7. 关于promise(一)

    该新特性属于 ECMAScript 2015(ES6)规范,在使用时请注意浏览器兼容性. 由于ES6原生提供Promise,所以无需安装Promise库.但在ES5环境下我们可以使用bluebird库 ...

  8. cell 和 cellHeight的先后执行顺序

    UITableView 在运行过程中,总是,先生成一个UITableViewCell ,然后一次这个cell的height.

  9. MorkDown 常用语法总结

    推荐一款很好用的markdown编辑器:http://www.typora.io/ 基本技巧: 代码高亮 如果你只想高亮语句中的某个函数名或关键字,可以使用``实现 通常编辑器根据diamagneti ...

  10. python操作memcached以及分布式

    memcached 是以 LiveJournal 旗下 Danga Interactive 公司的 Brad Fitzpatric 为首开发的一款软件.现在已成为 mixi.Facebook.Live ...