题4
题目
【2016 统考真题】已知由 (
设计一个尽可能高效的划分算法,满足
- 给出算法的基本设计思想。
- 根据设计思想, 采用 C 或 C++语言描述算法, 关键之处给出注释。
- 说明所设计算法的平均时间复杂度和空间复杂度。
分析
首先解决子集内元素求和的函数,考虑直接挨个遍历元素求和
再来考虑划分问题,直接暴力循环,设置一个gap作为两个子集数量之差的绝对值,让
直到
时间复杂度上,因为两层循环,内层n,外层也是n,总的就是
空间复杂度上,因为开了3个为n的数组,所以是
解
#include<bits/stdc++.h>
using namespace std;
const int N = 100000;
int big[N],a1[N],a2[N];
int n = 0;
int ds = 0; //s1-s2
int res_a1[N]; //划分的结果a1
int res_a2[N]; //划分的结果a2
int gap = 0x7fffffff;
int sum(int a*, int head, int end) {
int sum_res = 0;
for (int i = head; i < end; i++) {
sum_res += a[i];
}
return sum_res;
}
int main() {
cin >> n;
for(int i = 0 ;i<n;i++) {
cin >> big[i];
}
for(int i =2; i<n;i++) {
int n1 = i, n2 = n-i;
int sum_a1 = sum(int big*, 0, n1);
int sum_a2 = sum(int big*, n1, n);
int gap_temp = abs(n1-n2);
if(gap_temp < gap) { //如果gap更小
//同时s1-s2的绝对值更大
if(abs(sum_a1-sum_a2) > ds) {
gap = gap_temp;
ds = abs(sum_a1-sum_a2);
for(int j = 0; j<n1;j++) {
res_a1[j] = big[j];
}
for(int j = 0; j<n2;j++) {
res_a2[j] = big[j+n1];
}
}
}
//最后输出保存的两个子集,还有gap和s1-s2的值
for(int i = 0; i<n1;i++) {
cout << res_a1[i] << " ";
}
cout << endl;
for(int i = 0; i<n2;i++) {
cout << res_a2[i] << " ";
}
cout << endl;
cout << gap << " " << ds << endl;
return 0;
}