18.12.16 DSA 吉老师的汉诺塔

描述

吉老师的面前出现了一座汉诺塔!但是这个汉诺塔好像坏了,盘子并不是按照从大到小的顺序排列的……吉老师非常不开心,立志要把这个汉诺塔修好!吉老师每分钟可以交换挨在一起的两个盘子,吉老师希望用的时间最短,吉老师不会啊,你能帮帮吉老师吗?

输入

第一行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范围

猜你喜欢

转载自www.cnblogs.com/yalphait/p/10127181.html
dsa