java蓝桥杯练习 小朋友排队
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
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。
//java code
import java.util.*;
public class Main {
static class Child {
int high;//身高
int count;//交换次数
public Child(int high) {
this.high = high;
this.count = 0;
}
}
static void sort(Child c[]) {
if (c.length > 1) {
Child leftc[] = getHalf(c, 0);
Child rightc[] = getHalf(c, 1);
sort(leftc);
sort(rightc);
merge(c, leftc, rightc);
}
}
static Child[] getHalf(Child c[], int tag) {
int len = c.length;
Child half[];
if (tag == 0) {
half = new Child[len / 2];
for (int i = 0; i < half.length; i++) {
half[i] = c[i];
}
} else {
half = new Child[len-len / 2];
for (int i = 0; i < half.length; i++) {
half[i] = c[len / 2 + i];
}
}
return half;
}
static void merge(Child c[], Child leftc[], Child rightc[]) {
int i = 0, j = 0;
int lenL = leftc.length, lenR = rightc.length;
while (i < lenL && j < lenR) {//计算左半边中大于rightc[j]的数量
if (leftc[i].high > rightc[j].high) {
rightc[j].count += (lenL - i);
j++;
} else i++;
}
i = lenL - 1;
j = lenR - 1;
while (i >= 0 && j >= 0) {//计算右半边中小于leftc[i]的数量
if (leftc[i].high > rightc[j].high) {
leftc[i].count += (j + 1);
i--;
} else j--;
}
//归并排序
i = 0;
j = 0;
int t = 0;
while (i < lenL && j < lenR) {
if (leftc[i].high < rightc[j].high)
c[t++] = leftc[i++];
else
c[t++] = rightc[j++];
}
while (i < lenL)
c[t++] = leftc[i++];
while (j < lenR)
c[t++] = rightc[j++];
}
public static void main(String[] args) {
Main ss=new Main();
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Child child[] = new Child[n];
for (int i = 0; i < n; i++) {
int high = sc.nextInt();
child[i] = new Child(high);
}
ss.sort(child);
long ans=0;
for (int i = 0; i < n; i++) {
long count = child[i].count;
ans += count * (count + 1) / 2;
}
System.out.println(ans);
}
}