• [蓝桥杯][历届试题]小朋友排队


    时间限制: 1Sec 内存限制: 128MB 提交: 75 解决: 11

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

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

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

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

    如果有两个小朋友身高一样,则他们谁站在谁前面是没有关系的。 

    样例说明 
    首先交换身高为3和2的小朋友,再交换身高为3和1的小朋友,再交换身高为2和1的小朋友,每个小朋友的不高兴程度都是3,总和为9。 
    数据规模和约定 
    对于100%的数据,1< =n< =100000,0< =Hi< =1000000。 

    输入
    输入的第一行包含一个整数n,表示小朋友的个数。 
    第二行包含  n  个整数  H1  H2  …  Hn,分别表示每个小朋友的身高。
    输出
    输出一行,包含一个整数,表示小朋友的不高兴程度和的最小值。
    样例输入
    3 
    3  2  1 
    样例输出
    9

    #include<cstdio>
    #define maxn 100010
    struct data
    {
        int num,cnt;
    }A[maxn],temp[maxn];
    int n;
    //long long ans;
    long long ANS[100];
    void merge(int L1,int R1,int L2,int R2)
    {
        int k=0,i=L1,j=L2;
        while(i<=R1 && j<=R2)
        {
            if(A[i].num<=A[j].num)
    //如果A[i].num<A[j].num,则A[L2,j-1]的元素小于A[i],如果相等,则先存储上数组的元素,这个时候下数组的A[L2,j-1]仍然都满足小于A[i].num { A[i].cnt+=j-L2; temp[k++]=A[i++]; } else if(A[i].num>A[j].num)//A[i,R1]都大于A[j] { A[j].cnt+=R1-i+1; temp[k++]=A[j++]; } } //剩下上数组,那么剩下的元素都要移动下数组的元素个数 while(i<=R1) { A[i].cnt+=R2-L2+1; temp[k++]=A[i++]; } while(j<=R2) temp[k++]=A[j++]; //剩下下数组,就不需要移动 for(i=0;i<k;i++) A[L1+i]=temp[i]; } void mergeSort(int L,int R) { if(L<R) { int mid = (L+R)/2; mergeSort(L,mid); mergeSort(mid+1,R); merge(L,mid,mid+1,R); } } int main(void) { //FILE *in = fopen("input10.txt","r"); //fscanf(in,"%d",&n); //for(int i=0;i<n;i++) fscanf(in,"%d",&(A[i].num)); scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&(A[i].num)); mergeSort(0,n-1); for(int i=0;i<n;i++) { long long s = A[i].cnt; //ans+=s*(s+1)/2; ANS[1]+=s*(s+1)/2; int length=1; while(ANS[length]/10!=0) { ANS[length+1]+=ANS[length]/10; ANS[length]%=10; length++; } if(ANS[0]<length) ANS[0]=length; } //printf("%lld",ans); for(int i=ANS[0];i>=1;i--) printf("%d",ANS[i]); //printf(" "); return 0; }

    大致的思路:使用归并排序的思想求逆序对的思想,划分成为一个上数组,一个数组。
          上数组的元素往下数组方向移动,下数组的元素往上数组方向移动。
          上数组的元素往下数组方向移动,移动的长度是下数组中小于该元素的个数;
          下数组的元素往桑数组方向移动,移动的长度是上数组中大于该元素的个数。
          在结构体中记录移动的次数。
          由于数据较大,可以使用高精度加法进行计算。

    注意:这里使用long long 也是可以的

    #include<cstdio>
    #define maxn 100010
    struct data
    {
        int num,cnt;
    }A[maxn],temp[maxn];
    int n;
    long long ans;
    long long ANS[100];
    void merge(int L1,int R1,int L2,int R2)
    {
        int k=0,i=L1,j=L2;
        while(i<=R1 && j<=R2)
        {
            if(A[i].num<=A[j].num)//如果A[i].num<A[j].num,则A[L2,j-1]的元素小于A[i],如果相等,则先存储上数组的元素,这个时候下数组的A[L2,j-1]仍然都满足小于A[i].num 
            {
                A[i].cnt+=j-L2;
                temp[k++]=A[i++];
            }
            else if(A[i].num>A[j].num)//A[i,R1]都大于A[j] 
            {
                A[j].cnt+=R1-i+1;
                temp[k++]=A[j++];
            }
        }
        //剩下上数组,那么剩下的元素都要移动下数组的元素个数
        while(i<=R1) 
        {  
            A[i].cnt+=R2-L2+1;
             temp[k++]=A[i++]; 
        }     
        while(j<=R2) temp[k++]=A[j++]; //剩下下数组,就不需要移动 
        for(i=0;i<k;i++) A[L1+i]=temp[i];
    }
    void mergeSort(int L,int R)
    {
        if(L<R)
        {
            int mid = (L+R)/2;
            mergeSort(L,mid);
            mergeSort(mid+1,R);
            merge(L,mid,mid+1,R);
        }
    }
    int main(void)
    {    
        FILE *in = fopen("input10.txt","r");
        fscanf(in,"%d",&n);
        for(int i=0;i<n;i++) fscanf(in,"%d",&(A[i].num));
        //scanf("%d",&n);
        //for(int i=0;i<n;i++) scanf("%d",&(A[i].num));
        mergeSort(0,n-1);
        for(int i=0;i<n;i++)
        {
            long long s = A[i].cnt; 
            ans+=s*(s+1)/2;
        }
        printf("%lld",ans);
        
        return 0;
    }
  • 相关阅读:
    ansible-playbook基础
    ansible-playbook批量安装tomcat8版本
    linux
    PostgreSQL View(视图)
    PostgreSQL TRUNCATE TABLE
    PostgreSQL ALTER TABLE 命令
    redis主从环境搭建
    PostgreSQL 约束
    解决Chrome中Software Reporter Tool占CPU用过高
    C++标准模板库(STL)简介及应用
  • 原文地址:https://www.cnblogs.com/zuimeiyujianni/p/8727949.html
Copyright © 2020-2023  润新知