题目阅览
 n 个小朋友站成一排。现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友。
  每个小朋友都有一个不高兴的程度。开始的时候,所有小朋友的不高兴程度都是0。
  如果某个小朋友第一次被要求交换,则他的不高兴程度增加1,如果第二次要求他交换,则他的不高兴程度增加2(即不高兴程度为3),依次类推。当要求某个小朋友第k次交换时,他的不高兴程度增加k。
  请问,要让所有小朋友按从低到高排队,他们的不高兴程度之和最小是多少。
  如果有两个小朋友身高一样,则他们谁站在谁前面是没有关系的。
  
输入格式
  输入的第一行包含一个整数n,表示小朋友的个数。
  第二行包含 n 个整数 H1 H2 … Hn,分别表示每个小朋友的身高。
  
输出格式
输出一行,包含一个整数,表示小朋友的不高兴程度和的最小值。

样例输入1
3
3 2 1

样例输出1
9

样例说明
  首先交换身高为3和2的小朋友,再交换身高为3和1的小朋友,再交换身高为2和1的小朋友,每个小朋友的不高兴程度都是3,总和为9。

思路简介
先介绍一下第一次提交的代码,当然因为算法复杂超时了最后三个,这里的思路是将所有小朋友的身高和所在位置存储在数组中,并利用另外两个数组依次根据身高大小排序,最后再次根据小朋友所在位置筛选出满足比自身位置靠前,并且大于自身身高的人数和比自身位置靠后,但小于自己身高的人数,也就是交换的次序,再根据交换次序将小朋友不高兴程度递增,求和得出最终结果。

实现代码

#include <iostream>
#include <vector>
#include <algorithm>using namespace std;struct childInfo{int location;int valueNum;
};bool lowCompare(childInfo temp1,childInfo temp2){return temp1.valueNum>temp2.valueNum;
}bool upCompare(childInfo temp1,childInfo temp2){return temp1.valueNum<temp2.valueNum;
}int main(){int childNums;cin>>childNums;vector<childInfo> childLists;vector<childInfo> childLists1;vector<childInfo> childLists2;for(int i=0;i<childNums;i++){childInfo tempInfo;tempInfo.location=i;scanf("%d",&tempInfo.valueNum);childLists.push_back(tempInfo);childLists1.push_back(tempInfo);childLists2.push_back(tempInfo);}sort(childLists1.begin(),childLists1.end(),lowCompare);sort(childLists2.begin(),childLists2.end(),upCompare);long long int count=0;for(int m=0;m<childNums;m++){int sadNum=0;long long int count1=0,count2=0;int compareNum=childLists[m].valueNum,compareLoc=childLists[m].location;//比自身位置靠前,并且大于自身身高的人数for(int n=0;n<childNums;n++){if(compareNum<childLists1[n].valueNum){if(compareLoc>childLists1[n].location){sadNum++;count1+=sadNum;}}else{break;}}//比自身位置靠后,并且小于自身身高的人数for(int n=0;n<childNums;n++){if(compareNum>childLists2[n].valueNum){if(compareLoc<childLists2[n].location){sadNum++;count2+=sadNum;}}else{break;}  }count+=count1+count2;}cout<<count<<endl;return 0;
}

运行截图

改进方法
参考这位博主:归并排序
将每个小朋友交换次数是前面比他大的个数与后面比他小的个数之和,主要思路是对数组归并两次。
最终代码

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>using namespace std;struct childInfo{int location;int valueNum;
};int cnt[100005];void Merge_sort1(vector<childInfo>&tempChild,int left,int right)
{if(left>=right-1)return;int mid = (left+right)/2;Merge_sort1(tempChild,left,mid);Merge_sort1(tempChild,mid,right);int i=left,j=mid,t=0;childInfo *temp = new childInfo[right-left];while(i<mid || j<right){if(j>=right || i<mid && tempChild[i].valueNum<=tempChild[j].valueNum)temp[t++] = tempChild[i++];else{cnt[tempChild[j].location] += mid-i;temp[t++] = tempChild[j++];}}t=0;for(int k = left;k<right;k++)tempChild[k] = temp[t++];delete []temp;
}void Merge_sort2(vector<childInfo>&tempChild,int left,int right)
{if(left>=right-1)return;int mid = (left+right)/2;Merge_sort2(tempChild,left,mid);Merge_sort2(tempChild,mid,right);childInfo *temp = new childInfo[right-left];int i=mid-1,j=right-1,t=right-left-1;while(i>=left || j>=mid){if(i<left || j>=mid && tempChild[i].valueNum <= tempChild[j].valueNum)temp[t--] = tempChild[j--];else{cnt[tempChild[i].location] += j-mid+1;temp[t--] = tempChild[i--];}}t=0;for(int i=left;i<right;i++)tempChild[i] = temp[t++];delete []temp;
}
int main()
{int n;cin >> n;vector<childInfo> childLists;for(int i=0;i<n;i++){childInfo tempChild;tempChild.location = i;cin >> tempChild.valueNum;childLists.push_back(tempChild); }vector<childInfo> childLists1(childLists.begin(),childLists.end());Merge_sort1(childLists,0,childLists.size());Merge_sort2(childLists1,0,childLists1.size());long long sum =0;for(int i=0;i<childLists.size();i++)sum += 1ll*(1+cnt[i])*cnt[i]/2;cout << sum;return 0;
}

最终结果

蓝桥杯 历届试题 小朋友排队 C++相关推荐

  1. 蓝桥杯 - 历届试题 小朋友排队 C语言实现

     历届试题 小朋友排队 时间限制:1.0s   内存限制:256.0MB 问题描述 n 个小朋友站成一排.现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友. 每个小朋友都有一 ...

  2. [蓝桥杯][历届试题]小朋友排队(树状数组)

    题目描述 n 个小朋友站成一排.现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友. 每个小朋友都有一个不高兴的程度.开始的时候,所有小朋友的不高兴程度都是0. 如果某个小朋友 ...

  3. 蓝桥杯小朋友排队java_[蓝桥杯][历届试题]小朋友排队 (C++代码)

    #include #define maxn 100010 struct data { int num,cnt; }A[maxn],temp[maxn]; int n; //long long ans; ...

  4. [蓝桥杯][历届试题]国王的烦恼(反向+并查集)

    问题 1435: [蓝桥杯][历届试题]国王的烦恼 时间限制: 1Sec 内存限制: 128MB 提交: 802 解决: 213 题目描述 C国由n个小岛组成,为了方便小岛之间联络,C国在小岛间建立了 ...

  5. 蓝桥杯 - 历届试题 - 日期问题

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_33531813/article/details/79516258 </div>&l ...

  6. 蓝桥杯历届试题 地宫取宝 dp or 记忆化搜索

    问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被带到地宫的入口,国王要求他只能向右或向下行走. 走 ...

  7. 二分搜索,POJ2456,NYOJ 914, 区间移位-蓝桥杯-历届试题

    二分搜索是不断缩减可能解的范围来得到最优解, 因为每次是折半, 所以指数爆炸有多快,这个效率就有多高 POJ2456为例, 传送门 简而言之, 就是将牛之间的距离的最小值最大化. #include&l ...

  8. 蓝桥杯历届试题代码参考

    蓝桥杯历届试题代码参考 历届试题 核桃的数量 打印十字图 带分数 剪格子 错误票据 翻硬币 连号区间数 买不到的数目 大臣的旅费 幸运数 横向打印二叉树 危险系数 网络寻路 高僧斗法 格子刷油漆 农场 ...

  9. 问题 1433: [蓝桥杯][历届试题]危险系数(并查集and暴力)

    问题 1433: [蓝桥杯][历届试题]危险系数 时间限制: 1Sec 内存限制: 128MB 提交: 123 解决: 39 题目描述 问题描述 抗日战争时期,冀中平原的地道战曾发挥重要作用. 地道的 ...

最新文章

  1. JavaScript的前世今生
  2. 编写高质量代码改善C#程序的157个建议——建议133:用camelCasing命名私有字段和局部变量...
  3. qlabel文本改变信号_周明:NLP进步将如何改变搜索体验
  4. 大学使用python 编辑器_[雪峰磁针石博客]2018 最佳python编辑器和IDE
  5. Python 深浅copy 和文件操作
  6. nginx下部署vue项目概览 - (资源篇)
  7. 每次打印只能打打印一页
  8. csv文件-读取方式、字典
  9. 金蝶KIS旗舰版直接新增销售出库单使用说明,金蝶盘点机PDA仓库条码管理
  10. python画风羽及风羽定义
  11. Arithmetic problem | 吹爆n个气球,得到最多的分数
  12. AD(altium designer)15原理图与PCB设计教程(六)——印制电路板设计的基础知识
  13. 处处吻(粤语汉字英译)
  14. 重置ubuntu密码
  15. 英特尔Thunderbolt(雷电)控制器驱动
  16. 【备忘】Spring Boot技术栈博客企业前后端
  17. MySQL——10038错误
  18. 小ck活动机器人包包_你一定要入手的小ck包
  19. 哈姆雷特的机器人可以合体吗_饥荒哈姆雷特机器人wx-78怎么样 机器人wx-78人物属性详解...
  20. 无法参加2022年6月PMP考试怎么办?

热门文章

  1. 【突然断电后电脑无法开机】
  2. SSD固态硬盘颗粒SLC MLC TLC QLC有什么区别
  3. 关于mfc常用系统函数的使用及说明
  4. php调用lol数据库,计算lol战斗力
  5. Spring.NET企业架构实践之 JQuery + FlexiGrid + ASP.NET MVC + NVelocity + WCF + LINQ + NHibernate 综合应用
  6. 牛客网--关于合法括号序列判断
  7. C# 特性Description的值的获取
  8. python中的下划线_讲解
  9. MSRA显著性检测数据集
  10. P5587 打字练习