描述
吉老师的面前出现了一座汉诺塔!但是这个汉诺塔好像坏了,盘子并不是按照从大到小的顺序排列的……吉老师非常不开心,立志要把这个汉诺塔修好!吉老师每分钟可以交换挨在一起的两个盘子,吉老师希望用的时间最短,吉老师不会啊,你能帮帮吉老师吗?
输入
第一行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 }
照搬了之前的作业求逆序对。提示说得很清楚,坑点在于答案超过了int范围
原文地址:https://www.cnblogs.com/yalphait/p/10127181.html
时间: 2024-10-16 00:38:44