Beispiel #1
0
/* Permutation Sequence
The set [1,2,3,…,n] contains a total of n! unique permutations.

By listing and labeling all of the permutations in order,
We get the following sequence (ie, for n = 3):

"123"
"132"
"213"
"231"
"312"
"321"
Given n and k, return the kth permutation sequence.
Note: Given n will be between 1 and 9 inclusive.

康拓展开
一、康托展开:全排列到一个自然数的双射 Cantor Expand
X = an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0!
ai为整数,并且0<=ai<i(1<=i<=n)
适用范围:没有重复元素的全排列

二、全排列的编码:
{1,2,3,4,...,n}的排列总共有n!种,将它们从小到大排序,怎样知道其中一种排列是有序序列中的第几个?
如 {1,2,3} 按从小到大排列一共6个:123 132 213 231 312 321.想知道321是{1,2,3}中第几个大的数.
这样考虑:第一位是3,小于3的数有1、2 .所以有2*2!个.再看小于第二位,小于2的数只有一个就是1 ,所以有1*1!=1 所以小于32
的{1,2,3}排列数有2*2!+1*1!=5个.所以321是第6个大的数.2*2!+1*1!是康托展开.(注意判断排列是第几个时要在康托展开的结果后+1)

三、全排列的解码
如何找出第16个(按字典序的){1,2,3,4,5}的全排列?
1. 首先用16-1得到15
2. 用15去除4! 得到0余15
3. 用15去除3! 得到2余3
4. 用3去除2! 得到1余1
5. 用1去除1! 得到1余0

有0个数比它小的数是1,所以第一位是1
有2个数比它小的数是3,但1已经在之前出现过了所以是4
有1个数比它小的数是2,但1已经在之前出现过了所以是3
有1个数比它小的数是2,但1,3,4都出现过了所以是5
最后一个数只能是2

所以排列为1 4 3 5 2
 */
string getPermutation(int n, int k) {
    vector<int> factorial(n - 1, 1);
    vector<int> remainder(n - 1, 0);
    vector<int> remove_base(n, 0);
    string ans;

    for (int i = 0; i < n; ++i)
        remove_base[i] = i + 1;

    for (int i = 1; i < n - 1; ++i)
        factorial[i] = (i + 1) * factorial[i - 1];

    k = k - 1;
    for (int i = 0; i < n - 1; ++i) {
        remainder[i] = k / factorial[n - 2 - i];
        k = k % factorial[n - 2 - i];
    }
    auto it = remove_base.begin();
    for (int i = 0; i < n - 1; i++) {
        ans = ans + to_string(remove_base[remainder[i]]);
        remove_base.erase(it + remainder[i]);
    }
    ans = ans + to_string(remove_base[0]);
    return ans;
}
Beispiel #2
0
void tangent_4_inverse(double complex *x,int n, int lo)
{
  double complex temp;
    if(n == 2){
      // printf("LEVEL2\n");
      temp = x[lo];
      x[lo] = temp + x[lo+1];
      x[lo+1] = temp - x[lo+1];
    // print_complex(x,8);
    }
  else if(n > 2)
  {
      // printf("n = %d lo = %d\n",n,lo );
      int m = n/4;
      lo = lo+n/2;
      // printf("m = %d lo = %d\n",m,lo );
      tangent_8_inverse(x,m,lo+m);
      remove_base(x,lo+m,m,m);
      t_twist(x,n,m,lo+m);
      
      tangent_8_inverse(x,m,lo);
      remove_base(x,lo,m,m);
      t_untwist(x,n,m,lo);

      for (int i = lo; i < lo+m; ++i)
      {
        // printf("i = %d, m = %d\n",i,m );
        temp = x[i];
        x[i] = temp + x[i+m];
        x[i+m] = (temp - x[i+m])*-I;
      }
      // printf("AFTER\n");
      // print_complex(x,CPLXDIM);
      m = m*2;
      lo = lo -m;
      // printf("m = %d lo = %d\n",m,lo );
      tangent_4_inverse(x,m,lo);
      for(int i=lo; i < lo+m;++i){
        temp = x[i];
        x[i] = temp + x[i+m];
        x[i+m] = temp - x[i+m];
      }
  }
}