hdu 5122
Posted liqgnonqfu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 5122相关的知识,希望对你有一定的参考价值。
题目大意:
定义一种新的排序算法:随机的选一个数,若比它后一个大就交换,直到后一个比它小,完成一次操作。现在给定一个n个数的数列(保证是1~n的一个排列),问最少随机多少次?(T ≤ 200)(1 ≤ N ≤ 10 6).
思路:
对于每一个数,查看它与后面的数是否能构成逆序对就好。查找逆序对用归并排序时间复杂度就够了。
若从小到大排, 在归并排序每次合并两个区间时,左边的ai若大于右边的aj就说明aj与左边的区间的所有数都构成逆序对。这里要找每个数是否与后面的构成,就可以到过来记录,在按从大到小做归并排序。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 6 using namespace std; 7 8 int T,n,a[1000005],aa[1000005],anti[1000005]; 9 10 void msort(int l,int r) 11 { 12 int mid=(l+r)/2; 13 if(l+1<r) 14 { 15 msort(l,mid); 16 msort(mid,r); 17 } 18 int i=l,j=mid; 19 int k=l; 20 while(i<mid&&j<r) 21 { 22 if(a[i]>a[j]) 23 { 24 aa[k]=a[i]; 25 i++;k++; 26 } 27 else 28 { 29 anti[a[j]]++; 30 aa[k]=a[j]; 31 k++;j++; 32 } 33 } 34 if(j<r) 35 { 36 aa[k]=a[j]; 37 j++;k++; 38 } 39 if(i<mid) 40 { 41 aa[k]=a[i]; 42 i++;k++; 43 } 44 } 45 46 int main() 47 { 48 scanf("%d",&T); 49 for(int I=1;I<=T;I++) 50 { 51 scanf("%d",&n); 52 memset(a,0,sizeof(a)); 53 memset(anti,0,sizeof(anti)); 54 memset(aa,0,sizeof(aa)); 55 for(int i=1;i<=n;i++)scanf("%d",&a[n+1-i]); 56 msort(1,n+1); 57 int ans=0; 58 for(int i=1;i<=n;i++) 59 { 60 if(anti[i])ans++; 61 } 62 printf("Case #%d: %d ",I,ans); 63 } 64 return 0; 65 }
以上是关于hdu 5122的主要内容,如果未能解决你的问题,请参考以下文章
Luogu P5122 [USACO18DEC]Fine Dining 最短路
黑苹果原版镜像macOS Catalina 10.15.7 with OC 0.6.1 & Clover r5122 & PE
HDU4057 Rescue the Rabbit(AC自动机+状压DP)