首页 > 试题广场 >

已知由n(n≥2)个正整数构成的集合A={ak0≤k<n}

[问答题]
已知由 n(n≥2)个正整数构成的集合 A={ak|0≤k<n},将其划分为两个不相交的子集 A1和 A2,元素个数分 别是 n1和 n2,A1和 A2中元素之和分别为 S1和 S2。设计一个尽可能高效的划分算法,满足|n1-n2|最小且|S1-S2|最大。要求: 
(1)给出算法的基本设计思想。 
(2)根据设计思想,采用 C 或 C++语言描述算法,关键之处给出注释。 
(3)说明你所设计算法的平均时间复杂度和空间复杂度。
int quick_part(int A[],int n)
{
    int i=0,j=n-1,part=A[i],temp=0,i_0=i,j_0=j,sum=0;
    while(1)
    {
        while(i<j)
        {
            while(A[j]>part)j--;
            while(A[i]<part)i++;
            temp=A[j];
            A[j]=A[i];
            A[i]=temp;
        }
        A[i]=part;
        if(i==n/2)break;
        if(i>n/2)
        {
            j=i-1;
            i=i_0;
            j_0=j;
            i_0=i;
        }
        else
        {
            i=i+1;
            j=j_0;
            j_0=j;
            i_0=i;
        }
    }
    for(j=i;j<n;j++)
        {
            sum=sum+A[j];
        }
       for(j=0;j<i;j++)
        {
            sum=sum-A[j];
        }
        return sum;  
}

发表于 2021-12-17 15:20:39 回复(0)
int setPartition(int a[], int n, int lo1, int hi1) {
    int lo = lo1, hi = hi1;
    int pivot_val = a[lo];
    while (lo < hi) {
        while (lo < hi && a[hi] >= pivot_val) --hi;
        a[lo] = a[hi];
        while (lo < hi && a[lo] <= pivot_val) ++lo;
        a[hi] = a[lo];
    }
    a[lo] = pivot_val;
    int m = (n - 1) >> 1;
    if (lo == m) {
        return lo;
    } else if (lo < m) {
        return setPartition(a, n, lo + 1, hi1);
    } else return setPartition(a, n, lo1, lo - 1);
}

int gk(int *arr, int n) {
    int p = setPartition(arr, n, 0, n - 1) + 1;
    printf("p=%d\n", p - 1);
    int s1 = 0, s2 = 0;
    for (int i = 0; i < p; ++i) {
        s1 += arr[i];
    }
    while (p < n) {
        s2 += arr[p++];
    }
    return s2 - s1;
}  
递归代码
发表于 2024-09-06 20:43:04 回复(0)