• 小朋友排序(树状数组)


    问题描述
      n 个小朋友站成一排。现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友。

      每个小朋友都有一个不高兴的程度。开始的时候,所有小朋友的不高兴程度都是0。

      如果某个小朋友第一次被要求交换,则他的不高兴程度增加1,如果第二次要求他交换,则他的不高兴程度增加2(即不高兴程度为3),依次类推。当要求某个小朋友第k次交换时,他的不高兴程度增加k。

      请问,要让所有小朋友按从低到高排队,他们的不高兴程度之和最小是多少。

      如果有两个小朋友身高一样,则他们谁站在谁前面是没有关系的。
    输入格式
      输入的第一行包含一个整数n,表示小朋友的个数。
      第二行包含 n 个整数 H1 H2 … Hn,分别表示每个小朋友的身高。
    输出格式
      输出一行,包含一个整数,表示小朋友的不高兴程度和的最小值。
    样例输入
    3
    3 2 1
    样例输出
    9
    样例说明
      首先交换身高为3和2的小朋友,再交换身高为3和1的小朋友,再交换身高为2和1的小朋友,每个小朋友的不高兴程度都是3,总和为9。
    数据规模和约定
      对于10%的数据, 1<=n<=10;
      对于30%的数据, 1<=n<=1000;
      对于50%的数据, 1<=n<=10000;
      对于100%的数据,1<=n<=100000,0<=Hi<=1000000。

    开始运行超时的代码:(对了50%,但是不用long long 的话就只能过30%,所以以后蓝桥上果断用long long 数据类型)

    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    #include <cstring>
    #include <algorithm>  
    #include <iostream>
    using namespace std;
    int  main (){
    int  n,a[100005],temp[100005]={0};
    long long count[100005]={0}; 
    cin>>n;
    for(int i=0;i<n;i++)
    	scanf("%d",&a[i]);
    for(long long  i=1; i<n ;i++)
      for(long long  j=0; j<n-i ;j++){
      	if(a[j]>a[j+1]){
      		temp[j]++,temp[j+1]++; 
    		count[j]+=temp[j],count[j+1]+=temp[j+1];
      		long long  x=temp[j];
      		temp[j]=temp[j+1];
      		temp[j+1]=x;
      	    x=count[j];
      		count[j]=count[j+1];
      		count[j+1]=x;
      		x=a[j];
      		a[j]=a[j+1];
      		a[j+1]=x;
      	}	  
      }
      long long  sum=0;
     for(long long  i=0; i<n ;i++){
     	sum+=count[i]; 
     } 
     cout<<sum;
    return 0;
    }






    注意这里必须用long long 类型的变量。。。

    //值得注意的是由于0的lowbit还是0,所以a0是不能用的,这样会死在update中的while中,所以树状数组的值是从1开始的 
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #define LL long long
    const long long  M = 1e6+5;
    using namespace std;
    long long  sum[M], a[M], b[M], c[M];//sum为前n项和(打表产生)//a为开始输入的原始的值
                                    //b为临时记录之前有多少比当前值大的   c是真正的树状数组 
                                    
    long long  lowbit(long long   x){
    	return  x&-x;
    }
    
    void update(long long  x){
    	while(x < M){
    		c[x]++;
    		x+=lowbit(x);
    	}
    }
    
    long long   getsum(long long  x){
    	long long   sum=0;
    	while(x){
    		sum+=c[x];
    		x-=lowbit(x);
    	}
    	return sum;
    }
    
    int  main(){
    	long long   n,i;
    	cin>>n;
    	for(i=1; i<M;i++) //用来计算被交换i次其对应的不高兴值 
    	     sum[i] = sum[i-1]+i;
    	for(i = 0; i < n; ++ i){  //当前点跟左边点形成的逆序对数 
    		cin>>a[i];  
    	    update(a[i]+1);
    		b[i]=i+1-getsum(a[i]+1);
    	}
    	memset(c,0,sizeof(c));//由于在倒过来重新计数的时候需要重新试着c数组,所以将其初始化一下 
    	long long   res=0;
    	for(long long  i=n-1;i>=0;i--){ //当前点跟右边点形成的逆序对数 
    		update(a[i]+1);
    		res += sum[  b[i]+getsum(a[i]) ];		
    	}
    	cout <<res<<endl;
    	return 0;
    } 


  • 相关阅读:
    Selenium简单测试页面加载速度的性能(Page loading performance)
    Selenium Page object Pattern usage
    Selenium如何支持测试Windows application
    UI Automation的两个成熟的框架(QTP 和Selenium)
    分享自己针对Automation做的两个成熟的框架(QTP 和Selenium)
    敏捷开发中的测试金字塔(转)
    Selenium 的基础框架类
    selenium2 run in Jenkins GUI testing not visible or browser not open but run in background浏览器后台运行不可见
    eclipse与SVN 结合(删除SVN中已经上传的问题)
    配置Jenkins的slave节点的详细步骤适合windows等其他平台
  • 原文地址:https://www.cnblogs.com/zswbky/p/5431966.html
Copyright © 2020-2023  润新知