将一个数组拆分成两个数组,两个数组的差的绝对值最小

本文介绍了如何使用C语言实现一个算法,将一个正数数组拆分为两个子数组,使得两个子数组的和之差的绝对值最小。通过计算数组总和,确定中间值mid,并按与mid的接近程度依次分配元素到两个子数组,直至所有元素分配完毕。

要求如题,是qq群里一个大神让我敲的demo,花了2个小时,用c语言实现。但是数组的元素只能是正数!

思路是:
1).先求出数组的总和sum, sum/2=mid
2).然后将数组的元素跟mid比较,取出跟mid最接近的元素,放在第一个小数组里,然后在原来数组删除刚刚被取出的元素,更新原来数组
3).接着再取出离mid最近的元素,放在第二个小数组,在原数组中删除刚刚被取出的元素,更新原来数组
4).遍历原来数组,重复2和3,往后的元素放在第一个小数组或者第二个小数组,取决于两个小数组的所有元素的总和,哪个总和小就放在哪个小数组

#include<stdio.h>
void binaryMiun(int s[], int n);
int abs(int a);
int main() {
    int n, i, t;
    int s[n];
    printf("输入原始数组的个数: \n");
    scanf("%d", &n);
    printf("请输入数组元素:\n");
    for(i = 0; i < n; i++) {
        scanf("%d", &t);
        s[i] = t;
    } 
    printf("您输入的数组是:");
    for(i = 0; i < n; i++) {
        printf("%d   ", s[i]);
    }
    printf("\n");
    binaryMiun(s, n);
    return 0;
}
void binaryMiun(int s[], int n) {
    int i, h, mid, temp, k;
    int l[n];//第一个小数组
    int r[n];//第二个小数组
    int min;
    int lcount = 0;
    int rcount = 0;
    int sum = 0;
    int suml = 0;//第一个小数组元素总和
    int sumr = 0;//第二个小数组元素的总和
    int j = 0;
    //该for循环遍历数组求元素的总和sum
    for(int i = 0; i < n; i++) {
        sum += s[i];
    }
    //mid 为元素总和的一半
    mid = sum/2;
    for(h = 0; h < n;) {
        min = mid - s[0];
        //找出离mid最近的元素
        for(i = 0; i < n; i++) {
            temp = mid - s[i];
            if(temp <= min) {
                min = temp;
                //距离mid最近的元素的下标
                j = i;
            }
        }
        printf("出列的元素是------>%d\n", s[j]);
        //将取出的元素放在元素总和较小的数组
        if(suml <= sumr) {
            l[lcount++] = s[j];
            suml += s[j];
        }
        else {
            r[rcount++] = s[j];
            sumr += s[j];
        }
        //将刚刚在原数组取出的元素删除,更新原数组
        for(k = j; k < n; k++) {
            s[k] = s[k+1];
        }
        n--;
        printf("原数组变为:");
        for(k = 0; k < n; k++) {
            printf("%d   ", s[k]);
        }
        printf("\n");
    }
    printf("第一个数组:");
    for(i = 0; i < lcount; i++) {
        printf("%d   ", l[i]);
    }
    printf("\n第二个数组:");
    for(i = 0; i < rcount; i++) {
        printf("%ld   ", r[i]);
    }
    printf("\n拆分成两个数组的最小绝对值之差是:%d\n", abs(sumr-suml));
}
int abs(int a) {
    if(a < 0) 
        return -a;
    else
        return a;
}

测试:

这里写图片描述

评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值