数组中的反转次数.使用归并排序
Number of Inversion Count in an array. Using Merge Sort
对于那些不知道反转的人。
反演-
给定一个包含N个整数的数组A,数组的反转定义为任意一对索引(i,j),使得i <j和A[i]> A[j].
总之:
{inv}(A) = {(A(i),A(j)), i
例如,数组a={2,3,1,5,4}对于(2,1),(3,1),(5,4)的元素对有三种反转:(1,3),(2,3),(4,5)。
总倒置计数= 3.
嗯,我试着用标准归并排序来解决这个问题。以下是我认为它是如何工作的。
假设在某个阶段,partA和partb的归并排序是
partA -[1, 2, 3]。
partB -(4、5)
现在,设X为第一个数组partA的元素。Y =第二个数组partB.
如果X被复制到输出数组(i。e if X
Else如果Y被复制到输出数组(i。e(如果X> Y)。然后我们得到反转计数= count + mid - i+1。(i是该元素的位置)。因为它是按递增顺序排序的,所以位置j> i, X[j]> y的所有元素
下面是代码的进一步细节。
#include <iostream>
#include <vector>
using namespace std;
vector<int> a;
vector<int> c;
void merge(int low, int high, int mid);
void mergesort(int low, int high)
{
int mid;
if (low < high)
{
mid=(low+high)/2;
mergesort(low,mid);
mergesort(mid+1,high);
merge(low,high,mid);
}
return ;
}
int count ; //to store the inversion count
void merge(int low, int high, int mid)
{
int i, j, k;
i = low;
k = low;
j = mid + 1;
// standard merging from merge sort
while (i <= mid && j <= high)
{
if (a[i] < a[j])
{
c[k] = a[i];
k++;
i++;
}
else
{
c[k] = a[j];
k++;
j++;
// cout<<a[i]<<" "<<mid<<" "<<i<<"n";
count += mid - i+1; // This is where the trick occurs, if X > Y,
//eg. in [3, 4, 5] and [1,2]
//if(3>1) then 4,5 is obviously greater then 1, thus making count as mid - i+1
}
}
while (i <= mid)
{
c[k] = a[i];
k++;
i++;
}
while (j <= high)
{
c[k] = a[j];
k++;
j++;
}
for (i = low; i < k; i++)
{
a[i] = c[i];
}
}
int main()
{
//int a[20], i, b[20];
int T;
cin>>T;
while(T--){
//cout<<"enter the elementsn";
int N;
cin>>N;
count =0;
a.clear(); a.resize(N);
c.clear(); c.resize(N);
for (int i = 0; i < N; i++)
{
cin>>a[i];
}
mergesort(0, N-1);
cout<<count<<"n";
}
}
好,现在来看看我的疑问,我相信上面实现的逻辑是合法的,足以解决反转的数量,但由于一些奇怪的原因,它不是,我不确定是什么导致了这里的WA。
我被困在这个问题上有一段时间了,没能弄清楚。这不是家庭作业问题,只是我认为逻辑没有问题,代码仍然不起作用,可能的原因是什么?救命! .
Ideone Link - https://ideone.com/nmvl7i
关于Spoj的问题- http://www.spoj.com/problems/INVCNT/
注意:前两个测试用例工作得很好,当提交时我得到了WA。
您的解决方案的问题是结果可能大于整数范围,例如,如果序列为n, n - 1,…, 1,(不增加)反转次数将为n*(n - 1)/2,当n = 2*10^5时,结果将远远大于整数范围。
将int count
改为long long count
和
改变这一行:
count += mid - i + 1;
为:
count += (long long)mid - (long long) i + 1L;
你将得到接受的答案。
我接受的代码
- 在c++中尝试对对象数组进行排序时,出现std:bad_alloc错误
- 显示错误输出的简单数组排序程序
- 为什么我的排序算法会更改数组值
- 为什么我需要C++中不同的排序格式来对这个USACO代码上的数组和优先级队列进行排序
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 合并排序不排序自创建数组类 c++
- 带有枚举方向/类型的气泡排序结构数组
- 为什么指针在对二维数组进行排序时无法正常工作?
- 排序并行数组
- 如何在数组 c++ 中对字符串进行排序
- 为什么在此排序算法实现中,向量明显比数组慢?
- 如何对不在数组中的变量进行排序?
- C++数组与向量排序(在我的情况下,向量比数组慢~2.5倍(无优化))
- 按字母顺序对结构内数组变量中的名称进行排序
- 使用排序函数 c++ 对字符数组进行排序
- 使用 std::sort 对二维 c 数组进行排序
- c++中的数组和归并排序
- 归并函数中动态数组的归并排序
- 数组中的反转次数.使用归并排序
- 归并排序递归不清楚数组的排序是如何实现的,请帮助理解代码