蓝桥杯小朋友排队问题

/*问题描述
  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。*/

 

注:我写的答案只能在蓝桥杯的测试系统中拿到30分,是因为我使用了冒泡排序,到后面的测试样例内存使用超标导致。

但是答案的整体思想是没有问题的,胜在简单易懂,思路清晰。(因为本人不是专搞算法的,所以没有去追求完美的答案,如果想要完美答案的可以去学习一下树状数组)。

#include <iostream>
using namespace std;


/* run this program using the console pauser or add your own getch, system("pause") or input loop */


int main(int argc, char *argv[]) {
//平均每个交换次数一样时有最小不高兴程度
int motion=0,n=0,t=0,sum=0;
cin>>n;
int high[n],number[n];
for(int i=0;i<n;i++)
cin>>high[i];
for(int i=0;i<n;i++)
{
number[i]=0; //用来记录每个小朋友的交换次数
}
for(int i=0;i<n-1;i++)
for(int k=0;k<n-i-1;k++)
{
if(high[k]>high[k+1])
{
t=high[k];
high[k]=high[k+1];
high[k+1]=t;
++number[k+1];
++number[k];
t=number[k];//小朋友的位置变了,我的记录数组位置也要有相应的变化
number[k]=number[k+1];
number[k+1]=t;
}
}
for(int g=0;g<n;g++)//计算不高兴度
for(int f=0;f<n;f++)
if(number[f]!=0)
{
sum=sum+number[f];
number[f]=number[f]-1;
}

cout<<sum;
return 0;

}

 

其实不论如何先排哪个小朋友,不高兴度都是确定的(主要是因为它只能两两交换)。

该题的难点在于排序的算法复杂度以及如何去确定每个小朋友的不高兴度(要一一对应)。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Polices张

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值