算法 12.变换砖头

问题描述

小张在暑假时间来到工地搬砖挣钱。包工头交给他一项艰巨的任务,将一排砖头按照从低到高的顺序排好。可是小张的力量有限,每次只能交换相邻的两块砖头,请问他最少交换几次能够完成任务?

输入

第一行一个整数 n( 1 ≤ n ≤ 300000 1 \leq n \leq 300000 1n300000) ,表示砖头数量。
第二行 n 个整数 a i ( − 1000000000 ≤ a i ≤ 1000000000 a_i(-1000000000 \leq a_i \leq 1000000000 ai(1000000000ai1000000000) ,表示砖头的高度。

输出

一行一个整数,表示小张最多可以完成几项任务。

样例数据

输入(1)

5
4 1 3 2 5

输出(1)

4

代码

这个就 归并排序呗

 #include <stdio.h>//这是第十二题 变换砖头 
long long int bricks[300002];//定义一个数组来存放初始时砖的高度,需要把数组定义在主函数之外。 
long long int sorted_bricks[300002];//再定义一个数组来暂时存放排序好的砖,最后再导回到bricks里面 
long long count=0;//计数器,来记录有多少个逆序对 


void mergesort(long int left,long int right,long long int bricks[],long long int sorted_bricks[])//在这里定义归并排序的函数,略作修改来求逆序对。 
{
	if(right-left>0)//如果此时的待排序部分不为空,则继续 
	{
		long int middle=(left+right)/2;//首先尽量从中间阶段,进行下一步的归并操作 
		long int i=left;//保存左边的位置 
		long int p=left,q=middle+1;//保存中间的位置 
		mergesort(left,middle,bricks,sorted_bricks);//将此数列再分成两个子数列进行归并 
		mergesort(middle+1,right,bricks,sorted_bricks);//(这里对了就很奇怪,因为之前用快排的时候也是这样的递归写法,但是排出的结果是错误的) 
        while(p<=middle||q<=right)//排序的具体操作,两个子数列只要有一个为空,就继续填入,在此之前不断选出较小的来填入 
        {
            if(q>right||(p<=middle&&bricks[p]<=bricks[q]))
                sorted_bricks[i++] = bricks[p++];
            else
            {
                sorted_bricks[i++] = bricks[q++];
                count=count+middle-p+1;
            }
        }
        for(i = left; i <= right; i++)//将sorted_bricks中排好序的元素复制到bricks中
            bricks[i]=sorted_bricks[i];
    }
}
int main()
{
	long int n;
	scanf("%ld",&n);
	for(long int i=0;i<n;i++)
	{
		scanf("%lld",&bricks[i]);
	}//存放砖的状态
	//本题的思路是用归并排序求逆序对
	mergesort(0,n-1,bricks,sorted_bricks);//这里和讨论区里给出的归并算法不一样的是,C语言中需要把数组作为参数传入函数中。 
	printf("%ld\n",count);
	return 0;
} 
 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值