求种吧2728755329

您还未登陆,请登录后操作!
悬赏20爱心点
分享到微博
请选择登录方式
,谢谢!邮箱
您的举报已经提交成功,我们将尽快处理,谢谢!
大家还关注求种求种_百度知道
.少年野球を応援するママは息子のお友达に梦中的种子.我用神搜搜了几个都不能用.
我有更好的答案
百元店:「はねるのトびら」→百元店环节这是日本的一个综艺节目。此人为,图片出自
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁19510人阅读
求一个数列的逆序数
逆序对:数列a[1],a[2],a[3]…中的任意两个数a[i],a[j] (i&j),如果a[i]&a[j],那么我们就说这两个数构成了一个逆序对
逆序数:一个数列中逆序对的总数
如数列 3 5 4 8 2 6 9
(5,4)是一个逆序对,同样还有(3,2),(5,2),(4,2)等等
那么如何求得一个数列的逆序数呢?
方法1:一个一个的数
最简单也是最容易想到的方法就是,对于数列中的每一个数a[i],遍历数列中的数a[j](其中j&i),若a[i]&a[j],则逆序数加1,这样就能统计出该数列的逆序数总和
该方法的时间复杂度为O(n^2),具体过程就不细说了
方法2:归并的思想
有一种排序的方法是归并排序,归并排序的主要思想是将整个序列分成两部分,分别递归将这两部分排好序之后,再和并为一个有序的序列,核心代码如下
MergeSort(first,last)
If(first==last)
Int med=(first+last)/2;
MergeSort(first,med);
MergeSort(med+1,last);
Merge(first,last);
在合并的过程中是将两个相邻并且有序的序列合并成一个有序序列,如以下两个有序序列
Seq1:3 &4 &5
Seq2:2 &6 &8 &9
合并成一个有序序:
Seq:2 &3 &4 &5 &6 &8 &9
对于序列seq1中的某个数a[i],序列seq2中的某个数a[j],如果a[i]&a[j],没有逆序数,如果a[i]&a[j],那么逆序数为seq1中a[i]后边元素的个数(包括a[i]),即len1-i+1,
这样累加每次递归过程的逆序数,在完成整个递归过程之后,最后的累加和就是逆序的总数
实现代码如下:
const int LENGTH=100;
int temp[LENGTH];
//额外的辅助数组
int count=0;
void Merge(int * array,int first,int med,int last)
int i=first,j=med+1;
int cur=0;
while (i&=med&&j&=last)
if (array[i]&array[j])
temp[cur++]=array[i++];
temp[cur++]=array[j++];
count+=med-i+1;
//核心代码,逆序数增加
while (i&=med)
temp[cur++]=array[i++];
while (j&=last)
temp[cur++]=array[j++];
for (int m=0;m&m++)
array[first++]=temp[m++];
void MergeSort(int *array,int first,int last)
if (first==last)
int med=first+(last-first)/2;
MergeSort(array,first,med);
MergeSort(array,med+1,last);
Merge(array,first,med,last);
归并排序的复杂度为O(nlogn),当然此方法的复杂度也为O(nlogn)
方法3:用树状数组
还是以刚才的序列
3 &5 &4 &8 &2 &6 &9
大体思路为:新建一个数组,将数组中每个元素置0
0 &0 &0 &0 &0& 0& 0
取数列中最大的元素,将该元素所在位置置1
0& 0 &0 &0 &0& 0 &1
统计该位置前放置元素的个数,为0
接着放第二大元素8,将第四个位置置1
0& 0 &0 &1 &0& 0 &1
统计该位置前放置元素的个数,为0
继续放第三大元素6,将第六个位置置1
0& 0 &0 &1 &0& 1 &1
统计该位置前放置元素的个数,为1
这样直到把最小元素放完,累加每次放元素是该元素前边已放元素的个数,这样就算出总的逆序数来了
在统计和计算每次放某个元素时,该元素前边已放元素的个数时如果一个一个地数,那么一趟复杂度为O(n),总共操作n趟,复杂度为O(n^2),和第一种方法的复杂度一样了,那我们为什么还用这么复杂的方法
当然,在每次统计的过程中用树状数组可以把每一趟计数个数的复杂度降为O(logn),这样整个复杂度就变为O(nlogn)
树状数组是一种很好的数据结构,这有一篇专门描述的文章
将序列中的每个数按照从大到小的顺序插入到树状数组中,给当前插入节点及其父节点的个数加1,然后统计该节点下边及右边放置元素的个数
具体代码如下:
//用树状数组求逆序数
const int Length=8;
struct Node
int LowBit(int num)
return num&(num^(num-1));
//自定义排序方法
int cmp(const void * num1,const void * num2)
return ((Node*)num2)-&data-((Node *)num1)-&
//统计pos节点下方及右方节点元素的个数
int sum(int *TreeArray,int pos)
int result=0;
while (pos)
result+=TreeArray[pos];
pos-=LowBit(pos);
//使pos位置的节点及其父节点的元素个数加1
void INC(int *TreeArray,int pos)
while(pos&Length)
TreeArray[pos]++;
pos+=LowBit(pos);
void insertNum(int *TreeArray,Node * seq,int &reverseNum)
for (int i=1;i&Li++)
reverseNum+=sum(TreeArray,seq[i].pos);
//累加逆序数
INC(TreeArray,seq[i].pos);
//将该节点及父节点的数加1
int main(int argc, char* argv[])
int array[]={3,5,4,8,2,6,9};
Node seq[Length];
int TreeArray[Length];
memset(TreeArray,0,sizeof(TreeArray));
for (int i=1;i&Length+1;i++)
seq[i].data=array[i-1];
seq[i].pos=i;
//从大到小排序
qsort(seq+1,Length-1,sizeof(Node),cmp);
int reverseNum=0;
//边插入边计数
insertNum(TreeArray,seq,reverseNum);
cout&&reverseNum&&
版权声明:本文为博主原创文章,未经博主允许不得转载。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:40100次
排名:千里之外
原创:15篇
评论:24条
(1)(1)(1)(2)(4)(4)(2)新人求种_里番动画吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0可签7级以上的吧50个
本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:80,730贴子:
求鬼父全套
爱丽 真理奈 纱奈 由佳 千代子
等都觉得楼主的贴很赞
内&&容:使用签名档&&
保存至快速回贴
为兴趣而生,贴吧更懂你。&或求种…………_百度知道
求种…………
你有什么麻烦需要我帮忙,是遇见不开心的事情了吗?人订旦斥秆俪飞筹时船江一辈子短短几十年,很快就过去了,一定要珍惜,要开开心心过日子。
其他类似问题
为您推荐:
其他2条回答
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁}

我要回帖

更多关于 求种吧 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信