首页 > 其他 > 详细

POJ-2299-Ultra-QuickSort(分治+memcpy用法)

时间:2021-01-25 09:05:56      阅读:25      评论:0      收藏:0      [点我收藏+]

http://poj.org/problem?id=2299

题意:

给定一组有n个数的序列,每次交换相邻两个元素,至少多少次才能使序列为非递减序列。

输入包括多组数据,每组数据第一行为一个整数n(n=0时输入结束),接下来n行有个整数,每组数据输出一行,表示最少交换次数

思路:

实际上就是求这个序列的逆序数问题,采用归并排序,对子问题进行和并的过程中同时计算逆序数。

对长度为n的序列进行归并排序:若n为1,算法终止;否则,将这个序列分成左右两个子序列,对每个序列分别进行归并排序,然后将排好序的子序列进行合并。

在合并过程中,维护左右两个序列的下标,如果当前左边的值大于右边的值,则左边剩下的数都大于右边的这个数,此时应对逆序数更新,右边的下标向后移动;否则,左边的下标向后移动。

 

PS:

strcpy只能复制字符串;

memcpy可以复制任意内容(字符数组,整型,结构体,类等)

在头文件#include<string.h>或#include<cstring>中

原型:

void *memcpy(void *destin, void *source, unsigned n);

destin-:用于存储复制内容的目标数组

source-:指向要复制的数据源

n-:要被复制的字节数

 

代码:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<iomanip>
#include<algorithm>
#include<string.h>
#include<queue>

using namespace std;
const int maxn=5e5+10;
const int inf=2147483647;
typedef long long ll;

int a[maxn],l[maxn],r[maxn];
ll sum=0;

void mergesort(int s,int e)
{
    if(s==e) return ;
    int mid=(s+e)/2;

    mergesort(s,mid);
    mergesort(mid+1,e);

    memcpy(l+1,a+s,(mid-s+1)*4);
    memcpy(r+1,a+mid+1,(e-mid)*4);
    l[mid-s+2]=r[e-mid+1]=inf;
    int left_num=mid-s+1;
    int left_i=1,right_i=1;
    for(int i=s; i<=e; i++)
    {
        if(l[left_i]>r[right_i])
        {
            a[i]=r[right_i++];
            sum+=left_num;
        }
        else
        {
            a[i]=l[left_i++];
            left_num--;
        }
        
    }
}

int main()
{
    int n;
    while(cin>>n&&n)
    {
        sum=0;
        for(int i=1; i<=n; i++) cin>>a[i];
        mergesort(1,n);
        cout<<sum<<endl;
    }
    system("pause");
    return 0;
}

 

POJ-2299-Ultra-QuickSort(分治+memcpy用法)

原文:https://www.cnblogs.com/sweetlittlebaby/p/14322986.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!