poj1804 Brainman

//题意:此题和poj2299题意是一样的,只是输出做了些变换,所以先看poj2299

//思路:同poj2299直接见代码吧:

#include <iostream>
#include <cstdio>
#define maxx 1000000000
using namespace std;

__int64 cnt;

void cal(int *n, int l, int mid, int r)
{
    int len_l = mid - l + 1;
    int len_r = r - mid;
    int *left = new int[len_l+2];
    int *right = new int[len_r+2];
    left[len_l+1] = maxx;    //这里需要注意的当某个区间归并完后,另一个区间剩余元素直接相当于copy所以,给定越界值为最大值
    right[len_r+1] = maxx;    //同上
    int i, j;
    i = j = 1;
    for(; i <= len_l; i++)
        left[i] = n[l+i-1];
    for(; j <= len_r; j++)
        right[j] = n[mid+j];
    i = j = 1;
    for(int k = l; k <= r; ){
        if(left[i] <= right[j]){
            n[k++] = left[i++];
        }else{
            n[k++] = right[j++];
            cnt = cnt + len_l - i + 1;//主要在这里计算逆序数,自行体会一下
        }
    }
    delete left;
    delete right;
    return ;
}

void mergesort(int *n, int l, int r)
{
    if(l < r){
        int mid = (l+r)/2;
        mergesort(n, l, mid);
        mergesort(n, mid+1, r);
        cal(n, l, mid, r);
    }

    return ;
}

int main()
{
    int x;
    scanf("%d", &x);
    int a = 1;
    while(x--){
        int t;
        scanf("%d", &t);
        printf("Scenario #%d:\n", a++);
        cnt = 0;
        int *n = new int[t+1];
        n[0] = maxx;
        for(int i = 1; i < t+1; i++){
            scanf("%d", &n[i]);
        }
        mergesort(n, 1, t);
        printf("%I64d\n\n", cnt);
        delete n;

    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/small__snail__5/article/details/80202490