poj2299 Ultra-QuickSort
2014-05-11 18:22
204 查看
链接:http://poj.org/problem?id=2299
题意:有一个序列,求在只能相邻两数交换位置的情况下,交换几次使得其升序排列。
额,我看时间7000MS,,一开始我就用冒泡了。。。TLE。
应该用归并排序做,用的是求逆序对个数的方法。
【逆序对的个数=当且仅当数组a[]按紧邻两数才交换的方式(类似按冒泡排序的方式)排成有序序列所需的交换次数】
一开始抄了数据结构书上的一个归并排序的模板,尼玛,RE了N次。。。是书上的那个程序有问题吗?
这个题的输出要用__int64.之前一直在针对这一点,改成long long,改成“%lld”,"%l64d".,以为RE是这里的原因。其实不是的。
然后网上抄了一个,过了。还是贴一下代码吧,也是一个不错的归并排序的模板。
#include<stdlib.h>
#include<stdio.h>
#define MAXN 500105
#define INF 0x7fffffff
int a[MAXN],l[MAXN],r[MAXN];
__int64 ans;
void Merge(int low,int high)
{
int n1,n2,i,j,k;
n1=(high+low)/2-low+1;
n2=high-(high+low)/2; //n2=high-((high+low)/2+1)+1
for(i=1;i<=n1;i++)
l[i]=a[low+i-1];
for(j=1;j<=n2;j++)
r[j]=a[(high+low)/2+j];
l[n1+1]=INF; //设置哨兵,防止越界
r[n2+1]=INF;
i=j=1;
for(k=low;k<=high;k++)
if(l[i]<=r[j])
a[k]=l[i++];
else
{
a[k]=r[j++];
ans+=n1-i+1;
//逆序对数,因为l[i..n1]有序,l[i]>r[j],则l[i+1..n1]均大于r[j]
}
}
void MSort(int low,int high)
{
if(low<high)
{
int mid=(low+high)/2;
MSort(low,mid);
MSort(mid+1,high);
Merge(low,high);
}
}
void MergeSort(int n)
{
MSort(1,n);
}
int main()
{
int n,i;
while(scanf("%d",&n)!=EOF)
{
if(!n)return 0;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
ans=0;
MergeSort(n);
printf("%lld\n",ans);
}
return 0;
}
题意:有一个序列,求在只能相邻两数交换位置的情况下,交换几次使得其升序排列。
额,我看时间7000MS,,一开始我就用冒泡了。。。TLE。
应该用归并排序做,用的是求逆序对个数的方法。
【逆序对的个数=当且仅当数组a[]按紧邻两数才交换的方式(类似按冒泡排序的方式)排成有序序列所需的交换次数】
一开始抄了数据结构书上的一个归并排序的模板,尼玛,RE了N次。。。是书上的那个程序有问题吗?
这个题的输出要用__int64.之前一直在针对这一点,改成long long,改成“%lld”,"%l64d".,以为RE是这里的原因。其实不是的。
然后网上抄了一个,过了。还是贴一下代码吧,也是一个不错的归并排序的模板。
#include<stdlib.h>
#include<stdio.h>
#define MAXN 500105
#define INF 0x7fffffff
int a[MAXN],l[MAXN],r[MAXN];
__int64 ans;
void Merge(int low,int high)
{
int n1,n2,i,j,k;
n1=(high+low)/2-low+1;
n2=high-(high+low)/2; //n2=high-((high+low)/2+1)+1
for(i=1;i<=n1;i++)
l[i]=a[low+i-1];
for(j=1;j<=n2;j++)
r[j]=a[(high+low)/2+j];
l[n1+1]=INF; //设置哨兵,防止越界
r[n2+1]=INF;
i=j=1;
for(k=low;k<=high;k++)
if(l[i]<=r[j])
a[k]=l[i++];
else
{
a[k]=r[j++];
ans+=n1-i+1;
//逆序对数,因为l[i..n1]有序,l[i]>r[j],则l[i+1..n1]均大于r[j]
}
}
void MSort(int low,int high)
{
if(low<high)
{
int mid=(low+high)/2;
MSort(low,mid);
MSort(mid+1,high);
Merge(low,high);
}
}
void MergeSort(int n)
{
MSort(1,n);
}
int main()
{
int n,i;
while(scanf("%d",&n)!=EOF)
{
if(!n)return 0;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
ans=0;
MergeSort(n);
printf("%lld\n",ans);
}
return 0;
}
相关文章推荐
- poj 2299 Ultra-QuickSort 求逆序对
- 【POJ】2299 - Ultra-QuickSort(离散化 & (树状数组 | 线段树))
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort(逆序数 树状数组)
- poj 2299 Ultra-QuickSort (归并排序 求逆序数)
- POJ_2299 Ultra-QuickSort【归并排序】
- poj2299 Ultra-QuickSort 树状数组
- POJ 2299 Ultra-QuickSort(树状数组+离散化)
- poj 2299 Ultra-QuickSort 树状数组+离散化
- POJ 2299 Ultra-QuickSort (逆序数)
- poj2299——Ultra-QuickSort
- poj 2299 Ultra-QuickSort (归并排序,逆序数)
- poj 2299 Ultra-QuickSort(归并排序)||(树状数组+离散化)
- POJ 2299 Ultra-QuickSort (初学树状数组)
- POJ 2299 Ultra-QuickSort【逆序数&&离散化】
- poj 2299 Ultra-QuickSort(归并排序求逆序对)
- POJ 2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort 初级->数据结构->排序-归并排序
- poj-2299-Ultra-QuickSort-归并排序求逆序数--或树状数组
- POJ 2299 Ultra-QuickSort (树状数组+离散化)