目录
题目描述:
Description
小张在暑假时间来到工地搬砖挣钱。包工头交给他一项艰巨的任务,将一排砖头按照从低到高的顺序排好。可是小张的力量有限,每次只能交换相邻的两块砖头,请问他最少交换几次能够完成任务?
Input
第一行一个整数 n(1 - 300000 ) ,表示砖头数量。
第二行 n 个整数 (-1000000000-1000000000 ) ,表示砖头的高度。
Output
一个整数,表示最少交换几次能够完成任务。
乍一看:不就是冒泡
你要知道,交换,排序,最少步数。
第一个会想到冒泡,但是时间复杂度是n^2,所以一定会超时。
那么转换问题:用逆序数代替最小步数
把最小步数转换成求逆序数,但是其实本质还是冒泡排序,看完上面那篇文章你就理解了,或者直接用即可。
关键是,转换成求逆序数,你就可以在csdn上找出一大堆教程,常用的是归并排序求逆序数,至于用树状数组求,是高级玩法了,咱这种上csdn找题解的,就别掺和了,如果有时间,学一学倒是也不错,以后迟早要学树状数组的。
问题转换:归并排序是什么?怎么在归并排序中计数?
十大经典排序算法-归并排序算法详解_小小学编程的博客-CSDN博客_归并排序算法
这篇图画的好,也有实例,便于理解思想,然而不是c语言
归并排序(C语言)详解_爱前端的小菜的博客-CSDN博客_c语言归并排序
这篇是c语言,而且讲的也比较详细,但是他用的递归,递归一方面是速度会拖慢,我之前用斐波那契数列,和这个都是双递归,开到50个左右递归,就已经跑不动了;另一方面递归一层一层地理解起来稍微难一点;还有就是他代码写的稍微有点啰嗦。
实际上有非递归的方式。
逆序数的求法-csdn博客_i-Curve的博客-CSDN博客_逆序数怎么求
最终解答,这篇是c++,不过只用到个>>符号,你就把他当自动规定类型的scanf和printf好了
这篇还讲了树状数组,不过我是没时间研究了,等以后有题非用这算法不可,我才学
不得不提的是,这个人后面还装起来了,/2就除2,还用个>>1位运算装逼,我yue~
最后吐槽一波。
真的不要随便用单个字母当变量名,那个l和1太像了,关键是变量名含义不够清晰,不是一个好习惯。
代码:
#include<stdio.h>
#define SIZE 300010
int pos[SIZE], temp[SIZE];
long long ans = 0;
void sort(int, int, int);
void merge(int, int);
int main(void)
{
// freopen("input.txt", "r", stdin);
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &pos[i]);
merge(0, n - 1);
printf("%lld\n", ans);
return 0;
}
void sort(int left, int mid, int right)
{
int i = left, j = mid + 1;//i j 并列记录左右分部
int k = left; //k对应大部
//左右区都非空,取小记录
while (i <= mid && j <= right)
if (pos[i] > pos[j])
{
temp[k++] = pos[j++];
ans += (long long)((mid + 1) - i);//其实没必要,因为width是int范围内
//这个原理不明hhh
//大概是把i指向的大数搬到右边要的冒泡步数,也就是我们说的逆序数
}
else
temp[k++] = pos[i++];
//左右空一边,另一边录入
while (i <= mid)
temp[k++] = pos[i++];
while (j <= right)
temp[k++] = pos[j++];
//把temp写入pos,经过排序pos相当于在当前范围归并了一次
for (i = left; i <= right; i++)
pos[i] = temp[i];
}
void merge(int left, int right)
{
if (left < right) //一个以上就递归拆,一个以下,不排序就是排序了
{
int mid = (left + right) / 2;
merge(left, mid);
merge(mid + 1, right);
sort(left, mid, right);
//重点捋一下这个递归调用中sort
//sort放在递归调用之后,意味着sort其实是倒序执行的
//也就是说,顺着从大往小拆,然后反过来从小往大归并
//最后就是,从1个的情况,逐层排序,归并,更新pos
//最终在初始left和right区间内排序,得到最终的pos
}
}