Codevs3286 火柴排队
2015-10-25 20:51
477 查看
题目大意:给定两个长度为n的序列,序列中相邻的数可以相互交换。求至少交换多少次才能使火柴之间的距离和最小。
思路:可以用排序不等式证明,当每一根火柴与在各自排完序的序列中的序号相同者配对时,才有最小距离和。对于一个序列a,先确定其中元素相对于整个序列的位置,再用编号1、2、3进行定位,再对序列b中元素按已经在a中标好的标号与排名的对应关系对b进行标号,最后就是求逆序对个数了。
代码如下:
思路:可以用排序不等式证明,当每一根火柴与在各自排完序的序列中的序号相同者配对时,才有最小距离和。对于一个序列a,先确定其中元素相对于整个序列的位置,再用编号1、2、3进行定位,再对序列b中元素按已经在a中标好的标号与排名的对应关系对b进行标号,最后就是求逆序对个数了。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<cmath> using namespace std; const int maxn=100005; const int mod=99999997; int n; int a[maxn],b[maxn]; int ranka[maxn],rankb[maxn]; map<int,int> has; int id[maxn]; int tmpa[maxn],tmpb[maxn]; int ans=0,c[maxn]; void init() { scanf("%d",&n); for (int i=1;i<=n;++i) scanf("%d",&a[i]); for (int i=1;i<=n;++i) scanf("%d",&b[i]); } void getid() { memcpy(tmpa,a,sizeof(tmpa)); sort(tmpa+1,tmpa+n+1); for (int i=1;i<=n;++i) { int pos=lower_bound(tmpa+1,tmpa+n+1,a[i])-tmpa; ranka[i]=pos; } for (int i=1;i<=n;++i) has[ranka[i]]=i; memcpy(tmpb,b,sizeof(tmpb)); sort(tmpb+1,tmpb+n+1); for (int i=1;i<=n;++i) { int pos=lower_bound(tmpb+1,tmpb+n+1,b[i])-tmpb; rankb[i]=pos; } for (int i=1;i<=n;++i) id[i]=has[rankb[i]]; } void msort(int l,int r) { if (l==r) return; int mid=(l+r)/2; msort(l,mid); msort(mid+1,r); int i=l,j=mid+1,k=l; while (i<=mid && j<=r) { if (id[i]>id[j]) { c[k]=id[j]; ans=(ans+(mid-i+1)%mod)%mod; j++; k++; } else { c[k]=id[i]; i++; k++; } } while (i<=mid) { c[k]=id[i]; i++; k++; } while (j<=r) { c[k]=id[j]; j++; k++; } for (i=l;i<=r;++i) id[i]=c[i]; } int main() { init(); getid(); msort(1,n); printf("%d",ans); return 0; }
相关文章推荐
- C++实现八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序等
- Java实现八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序等
- Java排序算法总结之归并排序
- C++归并排序算法实例
- Javascript排序算法之合并排序(归并排序)的2个例子
- 归并排序的递归实现与非递归实现代码
- java二路归并排序示例分享
- java实现归并排序算法
- 归并排序的实现代码与思路
- 逆序对
- leetcode 虐我篇之(二) Two Sum
- In-place Merge Sort 原地并归排序
- 使用Java完成《算法导论》习题2.3-2
- 插入排序移动次数
- 归并排序 with Python
- 归并排序-逆序对的求解
- 排序算法的复杂度和稳定性
- 用python实现归并排序
- 归并排序
- 多种排序算法-java实现