【正经题解】火柴排队
2024-03-15 10:22:44
发布于:美国
10阅读
0回复
0点赞
首先,题目意思其实很容易分析,就是求逆序对数目,因为一定是最大对最大差值才会最小,所以肯定是第一排的最小对应第二排的最小,第一排的次小对第二排的次小,以此类推。接下来只需要求逆序对即可。
归并排序,归并排序采用的是二分的写法,并且当找到在小的数就把它加入一个新的数组里,所以实际上就是通过交换逆序数对来实现的,这样实现的时间复杂度是 ( )
#include<cstdio>
#include<algorithm>
using namespace std;
typedef struct n{
int num,ord;
}node;
node first_team[100010],second_team[100010];
int a[100010],b[100010],ans;
int compare(node x,node y)
{
return x.num<y.num;
}
void Merge(int l,int r)
{
if(l>=r) return ;
int mid=(l+r)/2;
Merge(l,mid);
Merge(mid+1,r);
int i=l,j=mid+1,k=l;
while(i<=mid&&j<=r)
{
if(a[i]>a[j])
{
b[k++]=a[j++];
ans+=mid-i+1;
ans%=99999997;
}
else b[k++]=a[i++];
}
while(i<=mid) b[k++]=a[i++];
while(j<=r) b[k++]=a[j++];
for(int i=l;i<=r;i++)
a[i]=b[i];
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&first_team[i].num);
first_team[i].ord=i;
}
for(int i=1;i<=n;i++)
{
scanf("%d",&second_team[i].num);
second_team[i].ord=i;
}
sort(first_team+1,first_team+n+1,compare);
sort(second_team****econd_team+n+1,compare);
for(int i=1;i<=n;i++)
a[first_team[i].ord]=second_team[i].ord;
Merge(1,n);
printf("%d",ans);
return 0;
}
这里空空如也
有帮助,赞一个