算法思想是归并排序么~3次~
[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
#include <time.h> #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define M 5 int ws[120] = {1}; void print(int s[], int n) { for (int i = 0; i < n; ++i) { printf("%d%c", s[i], "\n "[i < n - 1]); } } static int fac[] = {1, 1, 2, 6, 24, 120}; /* * 康托展开 */ int cantor(int sa[M]) { int result = 0; for (int i = 0; i < M; i++) { int count = 0; for (int j = i + 1; j < M; j++) { count += sa[i] > sa[j]; } result += count * fac[M - i - 1]; } return result; } /* * 逆康托展开 */ void unCantor(int sa[M], int x) { int i, j, l, t, h[10] = {0}; for (i = 1; i <= M; i++) { t = x / fac[M - i]; x -= t * fac[M - i]; for (j = 1, l = 0; l <= t; j++) if (!h[j]) l++; h[--j] = 1, sa[i - 1] = j; } } void swap(int sa[M], int beg, int end, int to) { int lren = end - beg + 1, sren[lren]; for (int i = beg; i <= end; ++i) sren[i - beg] = sa[i]; int stil[M - end + beg - 1], ltil = 0; for (int i = 0; i < M; ++i) { if (i >= beg && i <= end) continue; stil[ltil++] = sa[i]; } int pos = 0; for (int i = 0; i < to; ++i) sa[pos++] = stil[i]; for (int i = 0; i < lren; ++i) sa[pos++] = sren[i]; for (int i = to; i < ltil; ++i) sa[pos++] = stil[i]; } void dfs() { int sa[M], queue[120] = {0}, f = 0, r = 1; while (f < r) { int now = queue[f++]; for (int beg = 0; beg < M; ++beg) { for (int end = beg; end < M; ++end) { for (int to = 0; to < M - end + beg; ++to) { unCantor(sa, now); swap(sa, beg, end, to); int next = cantor(sa); if (ws[next]) continue; queue[r++] = next; ws[next] = ws[now] + 1; } } } } } int main() { int sa[M]; dfs(); for (int i = 0; i < 120; ++i) { unCantor(sa, i); printf("step: %d ", ws[i]); print(sa, M); } return 0; }
[此贴子已经被作者于2017-3-24 23:46编辑过]