题目描述
勤劳的贝西正在晒衣服。她把 N 根绳子系在了两根平行的木杆之间,每根木杆上有 N 个绳头。
由于贝西粗心大意,挂绳子的时候没有注意位置,所以一些绳子产生了交叉,布局非常混乱。如果从左向右看,第一根木杆上第 i 个绳头是第 A i 根绳子的,第二根木杆上第 j 个绳头是第 B j 根绳子的。
贝西希望把所有的绳子恢复成不交叉的状态。她只能进行一种交换操作,就是把某一根杆子上相邻的两个绳头交换位置。请问她需要做几步交换操作才能让所有的绳子没有交叉?
输入
• 第一行:单个整数 N,1 ≤ N ≤ 1000
• 第二行到第 N + 1 行:第 i + 1 行有两个整数 A i 和 B i ,1 ≤ A i ,B i ≤ N
输出
• 单个整数:表示最少做几次交换才能让所有绳子平行
为什么要发这篇的题解呢咳咳 因为我在考试时经旁边大哥提醒才想出来这道题的正解。。
这道题其实就是逆序对把左边编上序号1-n 然后求右边的逆序对就AC了
不多说上代码
#include<cstdio>
int n,x,ans,a[1001],b[1001],srt[1001];
void merge(int l, int m, int r)
{
int t=l,p=m+1,q=l;
while(t<=m&&p<=r)
{
if(b[t]>b[p])
{
srt[q++]=b[p++];
ans+=m-t+1;
}
else srt[q++]=b[t++];
}
while(t<=m)srt[q++]=b[t++];
while(q<=r)srt[q++]=b[p++];
for(int i=l;i<=r;i++)b[i]=srt[i];
}
void mergesort(int l, int r)
{
if(l<r)
{
int m=(l+r)/2;
mergesort(l,m);
mergesort(m+1,r);
merge(l,m,r);
}
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d%d",&x,&b[i]);
a[x]=i;
}
for(int i=0;i<n;i++)b[i]=a[b[i]];
printf("\n");
mergesort(0,n-1);//归并排序求逆序对
printf("%d\n",ans);
}
楼主QQ407694747 有问题可以加QQ一起讨论虽然这水题没什么可讨论的 (各路神犇请绕道