zoukankan      html  css  js  c++  java
  • 【HDOJ】1027 Ignatius and the Princess II

    这道题目最开始完全不懂,后来百度了一下,原来是字典序。而且还是组合数学里的东西。看字典序的算法看了半天才搞清楚,自己仔细想了想,确实也是那么回事儿。对于长度为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("
    ");
    56     }
    57 
    58     return 0;
    59 }
    View Code

    STL的next_permutation也可以直接实现:

     1 #include <iostream>
     2 #include <algorithm>
     3 using namespace std;
     4 
     5 #define MAXNUM 1005
     6 
     7 int array[MAXNUM];
     8 
     9 int main() {
    10     int n, m, k;
    11 
    12     while (cin>>n>>m) {
    13         for (int i=0; i<n; ++i)
    14             array[i] = i+1;
    15         k = 1;
    16         while (k++<m)
    17             next_permutation(array, array+n);
    18         cout <<array[0];
    19         for (int i=1; i<n; ++i)
    20             cout <<" "<<array[i];
    21         cout <<endl;
    22     }
    23     return 0;
    24 }
    View Code
  • 相关阅读:
    Spring中的注解@Service @Component @Controller @Repository区别
    hibhibernate中hql中的语句where语句查询List出现空
    转-sql中的case when的用法
    转-JS子窗口创建父窗口操作父窗口
    JS子父窗口互相取值赋值详解介绍
    转-JS之Window对象
    转-JS中document对象详解
    java设计优化--装饰者模式
    Java继承中属性、方法和对象的关系
    利用Ant脚本生成war包的详细步骤
  • 原文地址:https://www.cnblogs.com/bombe1013/p/3610996.html
Copyright © 2011-2022 走看看