历届试题 小朋友排队
时间限制: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源代码:
1 import java.util.Scanner; 2 public class Main { 3 static int max = 100005; 4 static Student[] stus = new Student[max]; 5 static Student[] r = new Student[max]; 6 static Student[] c = new Student[max]; 7 8 // 归并时,上数组的第一个元素与下数组的第一个元素相等,上数组的指针右移 9 static void Merge(Student[] a, int first, int last) { 10 int p, q, temp, mid; 11 mid = (first + last) / 2; 12 temp = first; 13 p = first; 14 q = mid + 1; 15 while (p <= mid && q <= last) { 16 if (a[p].h > a[q].h) { 17 a[q].s += mid + 1 - p;// 上数组的第一个元素比下数组的第一个元素大,下数组的第一个元素前面有mid+1-p个数比他大 18 c[temp++] = a[q++]; 19 } else { 20 a[p].s += q - 1 - mid; 21 // 上数组的第一个元素与下数组的第一个元素相等或者上数组的第一个元素比下数组的第一个元素小 22 // 注意:上数组的第一个元素与下数组的第一个元素相等时,也就是说下数组的第一个元素的前面的元素都比上数组的第一个元素小 23 // 上数组的第一个元素后面有q-1-mid个数比他小 24 c[temp++] = a[p++]; 25 } 26 } 27 while (q <= last) {// 下数组有剩余 28 c[temp++] = a[q++]; 29 } 30 q--; 31 while (p <= mid) {// 上数组有剩余,也就是说下数组的所有元素都比上数组剩下的元素小,故上数组每个元素t加q-mid,也就是下数组的元素个数 32 a[p].s += q - mid; 33 c[temp++] = a[p++]; 34 } int i = first; 35 for (; i <= last; i++) { 36 a[i] = c[i]; 37 } 38 } 39 static void MergeSort(Student[] a, int first, int last) { 40 if (first == last) { 41 return; 42 } 43 int mid = (first + last) / 2; 44 MergeSort(a, first, mid); 45 MergeSort(a, mid + 1, last); 46 Merge(a, first, last); } 47 public static void main(String[] args) { 48 Scanner in = new Scanner(System.in); 49 int n = in.nextInt(); 50 int i = 0; 51 for (; i < n; i++) { 52 Student st = new Student(); 53 st.h = in.nextInt(); 54 stus[i] = st; 55 } 56 MergeSort(stus, 0, n - 1); 57 long sum = 0;// 数的范围 58 for (i = 0; i < n; i++) { 59 long s = stus[i].s; 60 sum += (s + 1) * s / 2;// 求和 61 } System.out.println(sum); 62 } 63 } 64 class Student { 65 int h = 0; 66 int s = 0;// 统计左边比他大的个数和右边比他小的个数的总和 67 }
评测点序号 | 评测结果 | 得分 | CPU使用 | 内存使用 | 下载评测数据 |
---|---|---|---|---|---|
1 | 正确 | 10.00 | 124ms | 24.59MB | 输入 输出 |
2 | 正确 | 10.00 | 140ms | 24.58MB | 输入 输出 |
3 | 正确 | 10.00 | 187ms | 28.19MB | 输入 输出 |
4 | 正确 | 10.00 | 670ms | 50.99MB | 输入 输出 |
5 | 正确 | 10.00 | 546ms | 49.95MB | 输入 输出 |
6 | 正确 | 10.00 | 717ms | 65.85MB | 输入 输出 |
7 | 运行超时 | 0.00 | 运行超时 | 89.78MB | 输入 输出 |
8 | 运行超时 | 0.00 | 运行超时 | 87.65MB | 输入 输出 |
9 | 运行超时 | 0.00 | 运行超时 | 97.53MB | 输入 输出 |
10 | 运行超时 | 0.00 | 运行超时 | 87.85MB | 输入 输出 |
由于运行超时的输入输出数据过于庞大,这里暂不提供
时间: 2024-12-24 16:20:13