[快速排序]JZOJ 6307 安排
分析
题面直到晚上才明白啥意思
它并不是要我求最优方案,而是求出一种可行的在345678步中的方案!
所以这题的合并算法复杂度直接与答案挂钩
有根号n的算法,但是不能过4096的数据,所以需要优化到logn,容易想到快排,找到最长的一段逆序对,全部交换,分治即可
#include <iostream> #include <cstdio> using namespace std; const int N=4097; int n,a[N],ans,p[345679],q[345679],revornot; void Sort(int l,int r,int mid) { if (l>r||l==r||l>mid||mid>=r) return; int x=mid,y=mid+1; for (;l<x&&y<r&&a[x-1]>a[y+1];x--,y++); if (a[x]>a[y]) { for (int i=x,j=mid;i<j;i++,j--) swap(a[i],a[j]),p[++ans]=i,q[ans]=j; for (int i=mid+1,j=y;i<j;i++,j--) swap(a[i],a[j]),p[++ans]=i,q[ans]=j; for (int i=x,j=y;i<j;i++,j--) swap(a[i],a[j]),p[++ans]=i,q[ans]=j; Sort(l,mid,x-1);Sort(mid+1,r,y); } } void Solve(int l,int r) { if (l==r) return; int mid=l+r>>1; Solve(l,mid);Solve(mid+1,r);Sort(l,r,mid); } int main() { freopen("swap.in","r",stdin); freopen("swap.out","w",stdout); scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); Solve(1,n);revornot=ans; for (int i=1;i<=n;i++) scanf("%d",&a[i]); Solve(1,n); printf("%d\n",ans); for (int i=1;i<=revornot;i++) printf("%d %d\n",p[i],q[i]); for (int i=ans;i>revornot;i--) printf("%d %d\n",p[i],q[i]); }
在日渐沉没的世界里,我发现了你。