题目:Bubble Sort
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5775
题意:
for(int i=1;i<=N;++i)
for(int j=N,t;j>i;—j)
if(P[j-1] > P[j])
t=P[j],P[j]=P[j-1],P[j-1]=t;
给一小段冒泡排序的代码,问每一个数在排序过程中出现的最右边位置减最左边位置的差。
思路:
按照代码的运行过程,比如4 5 6 7 3 1 2,3最终是落在位置3,但有可能在排序过程中被1和2顶到后面去,所以其实就是求3后面比3小的数有几个(逆序数对,树状数组可解),然后3就会向后移动几位,那么最右边位置就是max(最终位置,移动过程中最靠右位置),最左边位置就是min(最终位置,初始位置)。
AC代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 int c[100010]; 6 int Lowbit(int x) 7 { 8 return x&(-x); 9 } 10 int getsum(int pos) 11 { 12 int sum=0; 13 while(pos>0) 14 { 15 sum+=c[pos]; 16 pos-=Lowbit(pos); 17 } 18 return sum; 19 } 20 void update(int pos,int num,int n) 21 { 22 while(pos<=n) 23 { 24 c[pos]+=num; 25 pos+=Lowbit(pos); 26 } 27 } 28 struct Node 29 { 30 int val; 31 int pos; 32 bool friend operator < (Node a,Node b) 33 { 34 return a.val<b.val; 35 } 36 }; 37 int min(int a,int b) 38 { 39 return a<b?a:b; 40 } 41 int max(int a,int b) 42 { 43 return a<b?b:a; 44 } 45 Node a[100010]; 46 int pos[100010]; 47 int ans[100010]; 48 int main() 49 { 50 int t,cas=1,n; 51 scanf("%d",&t); 52 while(t--) 53 { 54 scanf("%d",&n); 55 for(int i=1;i<=n;i++) 56 { 57 scanf("%d",&a[i].val); 58 a[i].pos=i; 59 pos[a[i].val]=i; 60 } 61 memset(c,0,sizeof(c)); 62 printf("Case #%d:",cas++); 63 sort(a+1,a+n+1); 64 for(int i=1;i<=n;i++) 65 { 66 ans[a[i].val]=getsum(n)-getsum(a[i].pos); 67 update(a[i].pos,1,n); 68 } 69 for(int i=1;i<=n;i++) 70 { 71 printf(" %d",max(pos[i]+ans[i],i)-min(pos[i],i)); 72 } 73 printf(" "); 74 } 75 return 0; 76 }