zoukankan      html  css  js  c++  java
  • 蓝桥杯历年试题 小朋友排队

    问题描述
      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。
     
    思路:
    逆序数的变形,不仅要求逆序数的对数,还要把对数明确到每一个单位,在求的过程中要注意排除相等的情况(如果有更方便的排除法麻烦留个言,感觉自己写的判断有点麻烦),用树状数组求也需要判断。
    使用了归并排序求逆序数的方法,把模板改了一下。
    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cmath>
    #include <map>
    #include <algorithm>
    #define LL long long int
    #define N 100005
    using namespace std;
    int cmp(int a,int b)
    {
        if(a==b) return 0;
        return a<b?-1:1;
    }
    struct node
    {
        int num;
        int ang;
    
    };
    LL ans[N];
    void MergeArr(node num[], int left, int mid, int right)
    {
        node AL[N], AR[N];
        int lenl=mid-left+1,lenr=right-mid;
        for (int i = 0;i < lenl;i++)
            AL[i] = num[left + i];
        for (int i = 0;i < lenr;i++)
            AR[i] = num[mid + 1 + i];
        int j = 0, k = 0,pos=left;
        int tempNum=-1,tempCnt=0;
        while (j < lenl&&k < lenr)
        {
            int fix=cmp(AL[j].num, AR[k].num);
            if (fix<=0)
            {
                num[pos++] = AL[j++],num[pos-1].ang+=k;
                if(num[pos-1].num==tempNum)
                    num[pos-1].ang-=tempCnt;
            }
            //else if(fix==-1) num[pos++] = AL[j++];
            else
                num[pos++] = AR[k++],num[pos-1].ang+=mid-(left+j)+1;//关键步骤
            if(fix>0)
            {
                if(num[pos-1].num==tempNum)
                    tempCnt++;
                else
                    tempNum=num[pos-1].num,tempCnt=1;
            }
    
        }
        while (j < lenl)
        {
            num[pos++] = AL[j++];
            num[pos-1].ang+=k;
            if(num[pos-1].num==tempNum)
                num[pos-1].ang-=tempCnt;
        }
        while (k < lenr)
            num[pos++] = AR[k++];
    }
    void MergeSort(node num[], int left, int right)
    {
        if (left < right)
        {
            int mid = (right + left) / 2;
            MergeSort(num, left, mid);
            MergeSort(num, mid+1, right);
            MergeArr(num, left, mid, right);
        }
    }
    LL mat(LL num)
    {
        return num*(num+1)/2;
    }
    node num[N];
    int n;
    int main()
    {
        cin.sync_with_stdio(false);
        while(cin>>n)
        {
            LL fuck=0;
            for(int i=0;i<n;i++)
                cin>>num[i].num,num[i].ang=0;
            MergeSort(num,0,n-1);
            for(int i=0;i<n;i++)
                fuck+=mat(num[i].ang);
    
            cout<<fuck<<endl;
        }
        return 0;
    }
  • 相关阅读:
    【Uvalive4960】 Sensor network (苗条树,进化版)
    【UVA 1151】 Buy or Build (有某些特别的东东的最小生成树)
    【UVA 1395】 Slim Span (苗条树)
    【UVA 10600】 ACM Contest and Blackout(最小生成树和次小生成树)
    【UVA 10369】 Arctic Network (最小生成树)
    【UVA 10816】 Travel in Desert (最小瓶颈树+最短路)
    【UVA 11183】 Teen Girl Squad (定根MDST)
    【UVA 11865】 Stream My Contest (二分+MDST最小树形图)
    【UVA 11354】 Bond (最小瓶颈生成树、树上倍增)
    【LA 5713 】 Qin Shi Huang's National Road System (MST)
  • 原文地址:https://www.cnblogs.com/LukeStepByStep/p/6387507.html
Copyright © 2011-2022 走看看