UVA 11925:Generating Permutations(冒泡排序 Grade D)

VJ题目链接

题意:n个数(n<300),是一个1~n的某个排列。有两种操作:操作1把前两个数换位置,操作2把第一个数移动到最后。问给出一个排列,问通过怎样的操作,能把1,2,3,...,n变到这种排列?要求操作数<2n^2

思路:正常冒泡排序的想法。如果前两个数,前面的大于后面的,则换(特例是n,1不能换)。否则,就用2的逆操作,把最后的数放前面。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define n 1023
int a[n+10];
int n;
int hd;

bool check() {
    for (int i = 1; i <= n; i++) {
        if (a[(hd+i-1)%n] != i) return false;
    }
    return true;
}

int stk[1000000];

void show() {
    for (int i = 0 ;i < n; i++) {
        printf("%d ", a[(hd+i)%n]);
    }puts("");
}

int main() {
    while (scanf("%d", &n) != eof) {
        if (n == 0) break;
        for (int i = 0; i < n; i++) {
            scanf("%d", &a[i]);
        }
        hd = 0;
        int top = 0;
        while (true) {
            if (check()) break;
            if (a[hd] > a[(hd+1)%n] && (!(a[hd] == n && a[(hd+1)%n] == 1))) {
                stk[top++] = 1;
                //printf("1");
                swap(a[hd], a[(hd+1)%n]);
                continue;
            } else {
                a[(hd-1+n)%n] = a[(hd+n-1)%n];
                stk[top++] = 2;
                //show();
                //printf("2");
                hd = (hd-1+n)%n;
            }
        }
        for (int i = top-1; i >= 0; i--) printf("%d", stk[i]);
        puts("");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/shinecheng/p/4003246.html