## Codeforces Round #598 (Div. 3) B. Minimize the Permutation
题意:一个n个元素的全排列(也就是1,2,3,4,5,…,n的任意一个排列)。有如下操作,可交换i位置和i+1位置的元素。所以显而易见一共有n-1种操作。限制是每种操作只能用至多一次,问能得到的最小的排列是什么。
思路:从1开始跑一边n的循环,1一定可以移动到第一个位置。然后所到之处的元素都依次后移。再来看2,如果2在1原来位置的左边,那么说明2不可动,如果在右边,说明可以移动到1原来的位置。就这样依次跑完for循环,每次记录可移动位置的第一个位置。
如果遇到pos[i] = i的情况,也注意要更新可移动位置的第一个位置。
(卡了好久啊……qaq……)
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
#define char char
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxN = 100 + 5;
int n;
int a[maxN]; //第i个位置上的值
int pos[maxN]; //数值i处在pos[i]的位置
int main()
{
int q; scanf("%d", &q);
while(q -- )
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++ )
{
scanf("%d", &a[i]);
pos[a[i]] = i;
}
int dead = 1;
for(int i = 1; i <= n; i ++ )
{
int tmp = pos[i];
for(int j = tmp; j > dead; j -- )
{
if(a[j] < a[j - 1])
{
swap(a[j], a[j - 1]);
swap(pos[a[j]], pos[a[j - 1]]);
}
}
dead = max(tmp, dead);
if(tmp == i)
dead = max(dead, tmp + 1);
}
for(int i = 1; i <= n; i ++ )
{
printf("%d%c", a[i], " \n"[i == n]);
}
}
return 0;
}