刷题笔记17——暴力、归并求数组小和(每个元素左边小于该元素的和)

题目描述

求在一个数组中, 每一个数左边比当前数小的数累加起来, 叫做这个数组的小和。
如给定数组[1,3,4,2,5]
1左边比1小的数, 没有;
3左边比3小的数, 1;
4左边比4小的数, 1、 3;
2左边比2小的数, 1;
5左边比5小的数, 1、 3、 4、 2;
所以小和为1+1+3+1+1+3+4+2=16

解法1:暴力解

刷题笔记17——暴力、归并求数组小和(每个元素左边小于该元素的和)_第1张图片

解法2:归并思想

刷题笔记17——暴力、归并求数组小和(每个元素左边小于该元素的和)_第2张图片

测试代码及结果

刷题笔记17——暴力、归并求数组小和(每个元素左边小于该元素的和)_第3张图片

#include 
#include 
using namespace std;

void printArray(int a[], int N) {
    for (int i = 0; i < N; ++i) {
        cout << a[i] << " ";
    }
    cout << endl;
}

int compare(int a[], int N) {
    int i, j;
    int sum = 0;
    for (i = 1; i < N; ++i) {
        for (j = 0; j < i; j++) {
            if (a[j] < a[i])
                sum += a[j];
        }
    }
    return sum;
}

int Merge(int a[], int left, int mid, int right) {
    int i = left;
    int j = mid + 1;
    int nums = right - left + 1;
    int *tmp = new int[nums];
    int t = 0;
    int sum = 0;
    while (i <= mid && j <= right) {
        if (a[i] < a[j]) {
            sum += ((right - j + 1) * a[i]);
            tmp[t++] = a[i++];
        } else {
            tmp[t++] = a[j++];
        }
    }
    while (i <= mid)
        tmp[t++] = a[i++];
    while (j <= right)
        tmp[t++] = a[j++];

    for (i = 0; i < nums; ++i) 
        a[left + i] = tmp[i];
    delete []tmp;
    return sum;
}

int MergeSort(int a[], int left, int right) {
    if (left == right) 
        return 0;
    int mid = left + ((right - left) >> 1);
    return MergeSort(a, left, mid) + MergeSort(a, mid + 1, right)
        + Merge(a, left, mid, right);
}

int smallSum(int a[], int N) {
    if (N < 2)
        return 0;
    return MergeSort(a, 0, N - 1);
}

int main (int argc, char* argv[]) {

    srand(time(NULL));
    const int size = 9;           // 随机生成的数组大小
    const int test_time = 10;      // 测试次数
    int a[size] = {0};             // 原始数组
    int tmp1[size] = {0};          // 测试数组
    int tmp2[size] = {0};          // 对比数组

    for (int cnt = 0; cnt < test_time; ++cnt) {
        for (int i = 0; i < size; ++i) {
            a[i] = rand() % 5 + 1;
        }
        for (int i = 0; i < size; ++i) {
            tmp1[i] = a[i];
            tmp2[i] = a[i];
        }
        // printArray(a, size);
        int res1 = smallSum(tmp1, size);
        int res2 = compare(tmp2, size);
        if (res1 == res2) {
            cout << "第 " << cnt << " 次测试 :";
            printArray(a, size);
            cout << "正确答案:" << res2 << " , 你的答案:" << res1 << endl;
        }
            
    }
    return 0;
}

你可能感兴趣的:(刷题)