P1116 车厢重组题解(c++)

传送门

题目描述

在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转 180 180 180 度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列。他退休后,火车站决定将这一工作自动化,其中一项重要的工作是编一个程序,输入初始的车厢顺序,计算最少用多少步就能将车厢排序。

输入格式

共两行。

第一行是车厢总数 N ( ≤ 10000 ) N( \le 10000) N(10000)

第二行是 N N N 个不同的数表示初始的车厢顺序。
:实际上数据中并不都在同一行,有可能分行输入)

输出格式

一个整数,最少的旋转次数。

样例 #1

样例输入 #1

4
4 3 2 1

样例输出 #1

6

思路1:冒泡排序

桥的长度最多能容纳两节车厢,如果将桥旋转180度,则可以把相邻两节车厢的位置交换可看出这道题很明显是可以用冒泡排序来做的,只需要在每次交换时将答案+1就好了。

代码如下:

#include 
using namespace std; 
int n, a[10010];
int ans = 0;
int main () {
	scanf("%d", &n);
	for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
	for(;;){
		bool flag = false;
		for(int i = 1; i < n; i++){
			if(a[i] > a[i + 1]){
				ans++;
				swap(a[i], a[i + 1]);//交换a[i]和a[i + 1]的值
				flag = true; 
			}
		}
		if(flag == false) break;//若以上循环没有交换,则排序已完成,退出循环 
	}
	printf("%d\n", ans);
	return 0;
}

思路2:直接统计交换次数

从冒泡排序的代码不难看出,只要数组里坐标较大的数比坐标较小的数小,则一定会发生一次移动
:一定是从前往后找,而不是将数组里全部的数都反复枚举一遍,否则会重复计算)

Code:

#include 
using namespace std; 
int n, a[10010];
int ans = 0;
int main () {
	scanf("%d", &n);
	for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
	for(int i = 1; i < n; i++){
		for(int j = i + 1; j <= n; j++)//枚举 
		{
			if(a[i] > a[j]) ans++; 
		}
	}
	printf("%d\n", ans);
	return 0;
}

你可能感兴趣的:(c++,算法,数据结构)