Minimize the Permutation

题目连接: Minimize the Permutation

题目:

给定一个长度为n的数组,数组由1到n的任意顺序的n个不同整数组成(这n个数保证不重复),对于给定的数列,最多可以执行n-1个操作(可能根本不执行任何操作)。第i种操作允许交换i和i+1两个位置的值。每种操作最多只能执行一次。操作可以按任意顺序执行。你的任务是通过按一定顺序执行某些给定操作找到最小字典序的数列. 例如,让我们考虑数列[5,4,1,3,2]。我们能得到的最小数列是[1,5,2,4,3],我们可以用以下方法来做:
执行第二种操作(交换第二和第三个元素)并获得数列[5,1,4,3,2];
执行第四种操作(交换第四个和第五个元素)并获得数列[5,1,4,2,3];
执行第三种操作(交换第三个和第四个元素)并获得数列[5,1,2,4,3]。
执行第一种操作(交换第一个和第二个元素)并获得数列[1,5,2,4,3];
另一个例子是[1,2,4,3]。通过执行第三种操作(交换第三和第四个元素),我们可以获得的最小可能置换是[1,2,3,4]。

Input
第一行输入一个t,代表以下有t组数据(1≤t≤100)
每组数据的第一行给一个n代表接下来输入一个大小为n的数列.(1≤n≤100)
每组数据的第二行给定这个数列每一位的数字 ai

Output
对于每一组数据,输出他能得到的最小字典序数列

Example
Input

4
5
5 4 1 3 2
4
1 2 4 3
1
1
4
4 3 2 1
Output
1 5 2 4 3
1 2 3 4
1
1 4 3 2

解题思路:

对于给定的几个数字, 如果让他们任意组合的结果最小, 那一定是从小到大依次排列. 而本题不允许我们任意组合, 因此我们无法保证各个数字从小到大依次排列, 但是若要结果最小, 让开头的数字尽可能小时所得的结果一定是优于让结尾数字尽可能大时的结果.
因此思路就有了, 我们要让靠前位置的数字尽可能的小, 即我们希望小数字在前.
那么我们不妨进行一次线性筛查, 倒着看整个序列, 把后一个数字比前一个数字大的排序进行交换, 这样最小的数字就可以被我们交换到首位(但是次小的数字并不一定在次位).
交换后或许还会有某些位置的交换次数没有用, 这时就要运用到贪心的思想, 看看交换后是否能让结果更小.

AC代码:

#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#define ll long long
using namespace std;
int a[200]; //存放数字
bool vis[200]; //用于表示当前位交换机会有没有用
int main(void)
{
	int t; cin >> t;
	while (t--) {
		memset(vis, 0, sizeof(vis));
		int n; scanf("%d", &n);
		for (int i = 0; i < n; i++) {
			scanf("%d", &a[i]);
		}
		for (int i = n - 1; i > 0; i--) { //要把小的往前换
			if (a[i] < a[i - 1]) {
				swap(a[i], a[i - 1]);
				vis[i - 1] = 1; //使用的是i-1位置的机会
			}
		}
		for (int i = 0; i < n - 1; i++) { //贪心
			if (!vis[i] && a[i] > a[i + 1]) {
				swap(a[i], a[i + 1]);
			}
		}
		for (int i = 0; i < n; i++) {
			printf("%d", a[i]);
			if (i == n - 1) printf("\n");
			else printf(" ");
		}
	}
	return 0;
}

如果你想不明白为什么会有那么一步贪心, 你可以这样理解:
如果序列是 4 3 1 2
第一次比较: 由于2比1大, 所以不交换 则3号下标的交换机会还在 结果:4 3 1 2
第二次比较: 由于1比3小, 所以交换 则2号下标的交换机会丧失 结果: 4 1 3 2
第三次比较: 由于1比4小, 所以交换 则1号下标的交换机会丧失 结果: 1 4 3 2
经过三次比较后, 我们3号下标的交换机会还在, 如果此时使用这次机会 则会让3 和 2进行换位, 结果为 1 4 2 3, 很明显, 结果比不进行贪心要小.这是因为我们进行完(i-1)交换时, 虽然保证了 i-1位置数字<i位置数字, 但是无法保证再接下来进行(i-2)交换时, i-2位置数字(交换后变为i-1位置数字)也一定比i位置数字小, 例如本例 3大于2.

END

发布了20 篇原创文章 · 获赞 0 · 访问量 518

猜你喜欢

转载自blog.csdn.net/weixin_45799835/article/details/104186593