给你一个有0--n-1数字组成的序列,然后进行这样的操作,每次将最前面一个元素放到最后面去会得到一个序列,那么这样就形成了n个序列,那么每个序列都有一个逆序数,找出其中最小的一个输出!
暴力。。线段树。。。归并排序。。。都可以
暴力:
#include "stdio.h"
#include "string.h"
#include "math.h"
#include "stdlib.h"
int main()
{
int n,i,j,t,ans,num[5010];
while (scanf("%d",&n)!=EOF)
{
for (i=1;i<=n;i++)
scanf("%d",&num[i]);
t=0;
for (i=1;i<n;i++)
for (j=i+1;j<=n;j++)
if (num[i]>num[j]) t++;
ans=t;
for (i=1;i<=n;i++)
{
t=t+(n-num[i]-1)-num[i];
if (t<ans) ans=t;
}
printf("%d\n",ans);
}
}
线段树:
#include "stdio.h"
#include "string.h"
struct comp
{
int l,r,sum;
} data[150010];
void build(int l,int r,int k)
{
int mid;
data[k].l=l;
data[k].r=r;
data[k].sum=0;
if (l==r) return ;
mid=(l+r)/2;
build(l,mid,k*2);
build(mid+1,r,k*2+1);
}
int search(int l,int r,int k)
{
int mid;
if (data[k].l==l && data[k].r==r)
return data[k].sum;
mid=(data[k].l+data[k].r)/2;
if (r<=mid) return search(l,r,k*2);
else
if (l>mid) return search(l,r,k*2+1);
else
return search(l,mid,k*2)+search(mid+1,r,k*2+1);
}
void updata(int n,int k)
{
int mid;
if (data[k].l==n && data[k].r==n)
{
data[k].sum=1;
return ;
}
mid=(data[k].l+data[k].r)/2;
if (n<=mid) updata(n,k*2);
else updata(n,k*2+1);
data[k].sum=data[k*2].sum+data[k*2+1].sum;
}
int main()
{
int n,i,x,ans,min;
int a[5100],b[5100];
while (scanf("%d",&n)!=EOF)
{
build(0,n-1,1);
ans=0;
for (i=1;i<=n;i++)
{
scanf("%d",&b[i]);
a[i]=search(b[i],n-1,1);
ans+=a[i];
updata(b[i],1);
}
min=ans;
for (i=1;i<=n;i++)
{
ans=ans-b[i]+(n-b[i]-1);
if (ans<min) min=ans;
}
printf("%d\n",min);
}
return 0;
}
归并排序:
#include "stdio.h"
#include "string.h"
#include "math.h"
int b[5010],a[5010],mark[5010];
int ans;
void merge(int l,int mid,int r)
{
int i,j,m;
i=l;
j=mid+1;
m=0;
while (i<=mid && j<=r)
{
if (a[i]<=a[j])
mark[m++]=a[i++];
else
{
mark[m++]=a[j++];
ans+=mid-i+1;
}
}
while (i<=mid)
mark[m++]=a[i++];
while (j<=r)
mark[m++]=a[j++];
for (i=0;i<m;i++)
a[l+i]=mark[i];
}
void mergesort(int l,int r)
{
int mid;
if (l<r)
{
mid=(l+r)/2;
mergesort(l,mid);
mergesort(mid+1,r);
merge(l,mid,r);
}
}
int main()
{
int n,i,min;
while (scanf("%d",&n)!=EOF)
{
for (i=0;i<n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
ans=0;
mergesort(0,n-1);
min=ans;
for (i=0;i<n;i++)
{
ans=ans+(n-b[i]-1)-b[i];
if (ans<min) min=ans;
}
printf("%d\n",min);
}
return 0;
}