Codeforces Round #598 (Div. 3) B. Minimize the Permutation

## 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;
}

发布了180 篇原创文章 · 获赞 54 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44049850/article/details/103615579