这道题目最开始完全不懂,后来百度了一下,原来是字典序。而且还是组合数学里的东西。看字典序的算法看了半天才搞清楚,自己仔细想了想,确实也是那么回事儿。对于长度为n的数组a,算法如下:
(1)从右向左扫描,找到满足a[i]<a[i+1]的第一个i,也就是i = max{i|a[i]<a[i+1]},同时也意味着a[i+1]~a[n]是升序;
(2)从右向左扫描,找到满足a[j]>a[i]的第一个j,也就是j = max{j|a[j]>a[i]},a[j]也是满足大于a[i]的最小数;
(3)交换a[i]与a[j];
(4)将a[j+1]与a[n]间的数字逆转。
直接实现算法:

 1 #include <stdio.h>
 2 
 3 #define MAXNUM 1005
 4 
 5 int array[MAXNUM];
 6 
 7 void chgonce(int n) {
 8     int i, j, k, tmp;
 9 
10     i = n-1;
11     while (i && array[i]>array[i+1])
12         i--;
13 
14     k = 0;
15     j = n;
16     while (j && array[j]<array[i])
17         j--;
18 
19     if (array[j] > array[i])
20         k = 1;
21 
22     if (k) {
23         tmp = array[j];
24         array[j] = array[i];
25         array[i] = tmp;
26 
27         // reverse
28         for (k=i+1; k*2<=n+i+1; ++k) {
29             tmp = array[k];
30             array[k] = array[n+i+1-k];
31             array[n+i+1-k] = tmp;
32         }
33     }
34 }
35 
36 int main() {
37     int n, m;
38     int i, k;
39 
40     while (scanf("%d %d", &n, &m) != EOF) {
41         for (i=1; i<=n; ++i) {
42             array[i] = i;
43         }
44         k = 1;
45         while (k<m) {
46             chgonce(n);
47             ++k;
48         }
49         for (i=1; i<=n; ++i) {
50             if (i==1)
51                 printf("%d", array[i]);
52             else
53                 printf(" %d", array[i]);
54         }
55         printf("\n");
56     }
57 
58     return 0;
59 }
View Code

相关文章:

  • 2021-11-28
  • 2022-12-23
  • 2021-07-19
  • 2021-08-06
  • 2022-12-23
  • 2022-02-02
猜你喜欢
  • 2021-12-30
  • 2021-11-20
  • 2022-01-01
  • 2021-12-23
  • 2022-12-23
  • 2022-02-23
相关资源
相似解决方案