经典算法详解(8)数的分组

简介: 题目:有10个任意的正整数,将其分为两组A和B,要求组A中每个数据的和与组B中每个数据的和之差的绝对值最小。请设计算法实现数的分组(找出一个答案即可)。C++版本: 1 #include 2 3 using namespace std; 4 5 void get_groupAB(i...

题目:有10个任意的正整数,将其分为两组A和B,要求组A中每个数据的和与组B中每个数据的和之差的绝对值最小。请设计算法实现数的分组(找出一个答案即可)。

C++版本:

 1 #include<iostream>
 2 
 3 using namespace std;
 4 
 5 void get_groupAB(int arr[]) {
 6     int sum_a, sum_b;
 7     int index, difference=0;
 8     int i,i_copy;
 9     //数组所有的元素求和给difference赋初值
10     for ( i = 0; i < 10; i++) {
11         difference += arr[i];
12     }
13     //从0000000000到1111111111,尾数为零时,对应的数组元素划分给a数组,否则划分给b数组
14     for ( i = 0; i < 0x3FF; i++) {            
15         sum_a = 0, sum_b = 0;
16         i_copy=i;
17         for (int j = 0; j < 10; j++) {
18             if ((i_copy & 1) == 0) {
19                 sum_a += arr[9 - j];
20             }
21             else {
22                 sum_b += arr[9 - j];
23             }
24             i_copy >>= 1;
25         }
26         if (difference > abs(sum_a - sum_b)) {
27             difference = abs(sum_a - sum_b);
28             index = i;            //存储最小值对应的索引
29         }
30         if (difference == 0) {
31             break;
32         }
33     }
34     //存储分组
35     int sub_a[10], sub_b[10];
36     int count_a=0, count_b=0;
37     for (i = 0; i < 10; i++) {
38         if ((index & 1) == 0) {
39             sub_a[count_a] = arr[9 - i];
40             count_a++;
41         }
42         else {
43             sub_b[count_b] = arr[9 - i];
44             count_b++;
45         }
46         index >>= 1;
47     }
48     //输出显示部分
49     cout << "group A:" << endl;
50     for (i = 0; i < count_a; i++) {
51         cout << sub_a[i] << endl;
52     }
53     cout << "group B:" << endl;
54     for (i = 0; i < count_b; i++) {
55         cout << sub_b[i] << endl;
56     }
57     cout << "difference:" << difference << endl;
58 }
59 
60 int main(int argc, char *argv[]) {
61 
62     int arr[10];
63     int i=0;
64     while (i < 10) {
65         cin >> arr[i];
66         i++;
67     }
68     get_groupAB(arr);
69     getchar();
70     getchar();
71     return 0;
72 }

思路:可以用一个10位的二进制数表示,对应位置为零时,分给一个组,为1时分给另外一个组;任何一个数都可以分给组A或者组B两种情况,故总的情况共有2^10,即1024种,其中不能全给A,也不能全给B,所以总共1024-2=1022种情况,进行枚举即可。另外如果出现差值为0时可以马上终止循环,因为不可能出现比0小的数了。

相关文章
|
4月前
|
算法 测试技术 C++
【动态规划】【前缀和】【数学】2338. 统计理想数组的数目
【动态规划】【前缀和】【数学】2338. 统计理想数组的数目
|
27天前
|
算法
LeetCode第39题组合总和
LeetCode第39题"组合总和"的解题思路和技巧,采用回溯法通过递归代替多层嵌套循环,有效解决组合问题。
LeetCode第39题组合总和
|
27天前
|
算法
LeetCode第40题组合总和II
LeetCode第40题"组合总和II"的解题策略,涉及排序、去重和使用标记数组避免重复组合,通过回溯法实现递归组合。
LeetCode第40题组合总和II
|
4月前
|
人工智能 BI
经典问题之区间分组
经典问题之区间分组
|
4月前
|
存储 算法
算法题解-组合总和3
算法题解-组合总和3
|
4月前
|
Java 索引
leetcode-39:组合总和
leetcode-39:组合总和
31 0
|
4月前
|
Java
leetcode-377:组合总和 Ⅳ
leetcode-377:组合总和 Ⅳ
30 0
|
4月前
|
Java
leetcode-40:组合总和 II
leetcode-40:组合总和 II
37 0
|
机器学习/深度学习 算法 安全
LeetCode - #40 组合总和 II
不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。
leetcode:39.组合总和
给定一个无重复元素的数组 candidates和一个目标数 target,找出 candidates中所有可以使数字和为 target的组合。
61 0