描述
吉老师的面前出现了一座汉诺塔!但是这个汉诺塔好像坏了,盘子并不是按照从大到小的顺序排列的……吉老师非常不开心,立志要把这个汉诺塔修好!吉老师每分钟可以交换挨在一起的两个盘子,吉老师希望用的时间最短,吉老师不会啊,你能帮帮吉老师吗?
输入
第一行1个整数N。
第二行为N 个非负整数,按从下到上的顺序给出每个盘子的大小。
对于50%的数据,2<=N<=1000。
对于100%的数据,2<=N<=100000。输出一个整数,表示最少需要交换多少次相邻的盘子才能将盘子递减排列。同样大小的盘子应该排在一起。
样例输入
5
1 3 10 8 5
样例输出
7
提示
吉老师经过多次尝试,发现最优情况下的每次交换中,一定是将小盘子放到大盘子的上面,这样它们就从逆序变成了顺序,而且只有这一对盘子从逆序变成了顺序,所以总共逆序的盘子对数恰好减少一。而当没有逆序的盘子时,汉诺塔就修好啦。
题解
1 #include <iostream>
2 #include <string.h>
3 #include <algorithm>
4 #include <stack>
5 #include <string>
6 #include <math.h>
7 #include <queue>
8 #include <stdio.h>
9 #include <string.h>
10 #include <vector>
11 #include <fstream>
12 #define maxn 100005
13 #define inf 999999
14 #define cha 127
15 using namespace std;
16
17 int n;
18 int plate[maxn], tmp[maxn];
19 long sum;
20
21 void mysort(int left,int right) {
22 if (left >= right)return;
23 int mid = (left + right) / 2;
24 mysort(left, mid), mysort(mid + 1, right);
25 int i = left, j = mid + 1, p = left;
26 while (i <= mid && j <= right) {
27 if (plate[i] >= plate[j])
28 tmp[p++] = plate[i++];
29 else {
30 tmp[p++] = plate[j++];
31 sum += mid - i + 1;
32 }
33 }
34 while (i <= mid)
35 tmp[p++] = plate[i++];
36 while (j <= right)
37 tmp[p++] = plate[j++];
38 for (int p = left; p <= right; p++)
39 plate[p] = tmp[p];
40 }
41
42 void init() {
43 scanf("%d", &n);
44 for (int i = 1; i <= n; i++)
45 scanf("%d", &plate[i]);
46 mysort(1, n);
47 printf("%ld\n", sum);
48 }
49
50 int main()
51 {
52 init();
53 return 0;
54 }
View Code
照搬了之前的作业求逆序对。提示说得很清楚,坑点在于答案超过了int范围