题目描述
在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转 180 180 180 度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列。他退休后,火车站决定将这一工作自动化,其中一项重要的工作是编一个程序,输入初始的车厢顺序,计算最少用多少步就能将车厢排序。
输入格式
共两行。
第一行是车厢总数 N ( ≤ 10000 ) N( \le 10000) N(≤10000)。
第二行是 N N N 个不同的数表示初始的车厢顺序。
输出格式
一个整数,最少的旋转次数。
样例 #1
样例输入 #1
4
4 3 2 1
样例输出 #1
6
解析
一、主要思路
- 直接做冒泡排序。
根据题意,只能相邻两个进行交换,正符合冒泡排序的特点。下面是冒泡排序的核心代码。
for(int i = 0; i < n; i ++){
for(int j = n-1; j > i; j--){
if(a[j]<a[j-1]){
swap(a[j], a[j-1]);
sum ++;
}
}
}
- 找到逆序对就可以了,无需进行排序。
核心代码如下:
for(int i = 1; i < n; i ++){
for(int j = 0; j < i; j ++){
if(a[j] > a[i]){
sum ++;
}
}
}
二、代码
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
int a[n+5];
for(int i = 0; i < n; i ++){
cin >> a[i];
}
int sum = 0;
for(int i = 0; i < n; i ++){
for(int j = n-1; j > i; j--){
if(a[j]<a[j-1]){
swap(a[j], a[j-1]);
sum ++;
}
}
}
// 查看了洛谷题解之后,发现只需要找逆序对就可以了,无需做交换。
// for(int i = 1; i < n; i ++){
// for(int j = 0; j < i; j ++){
// if(a[j] > a[i]){
// sum ++;
// }
// }
// }
cout << sum;
}
三、注意点
可以不用进行排序。
文章描述了一个利用桥面旋转来调整车厢顺序的问题,转化为寻找最少交换次数(即逆序对数量)。冒泡排序的思路被提及,但实际只需计算逆序对即可。给出了两种代码实现,一种完整冒泡排序,另一种仅计算逆序对。注意点在于不需要实际执行车厢交换。
238





