美文网首页NOIP之路
康托展开及其逆运算实现 C++

康托展开及其逆运算实现 C++

作者: 静_谷 | 来源:发表于2018-07-14 22:47 被阅读1次

康托展开

康托展开

  • 求一个数在其全排列的次序

  • 规定a[n]为 在第n位后面且比其数值小的数字个数与 (n-1)! 的乘积,则此数次序为a[1..n]的总和+1;比如52341的次序为(4*4!+1*3!+1*2!+1*1!+0*0!)+1

  • 例码

    int fac(int t){
      if(t==0)    return 0;
      if(t==1)    return 1;
      return fac(t-1)*t;
    }
    int cantor(int num){
      int ans=0;
      vector <int> a;
      while(num!=0){
          a.push_back(num%10);
          num/=10;
      }
      for(int i=0;i<a.size();i++){
          int cnt=0;
          for(int j=i-1;j>=0;j--)
              if(a[i]>a[j])
                  cnt++;
          ans+=fac(i)*cnt;
      }
      return ans+1;
    }
    

逆运算

  • 通过在全排列中的次序求出这个数

  • 先自减一作为第一轮的被除数,从第1位到第n-1位依次循环,被除数除以(n-1)!,设其商数为m,余数为r,则这个数的第n位是数组a[1..n]还未被标记中第m+1小的数字,标记这个数字,r作为下一轮的被除数;第n位即最后数组a[1..n]还未被标记的数字

  • 例码

    int fac(int t){
      if(t==0)    return 0;
      if(t==1)    return 1;
      return fac(t-1)*t;
    }
    int get_from_cantor(int num, int len){
      num--;
      int m=1,ans=0;
      bool *book = new bool[len+1];
      for(int i=1;i<len+1;i++)
          book[i]=1;
      for(int i=len;i>=2;i--){
          int t=fac(i-1);
          m=num/t+1;
          while(book[m]==0){
              m++;
          }
          book[m]=0;
          ans*=10;
          ans+=m;
          num%=t;
      }
      m=1;
      while(book[m]==0){
          m++;
      }
      ans*=10;
      ans+=m;
      delete [] book;
      return ans;
    }
    

相关文章

  • 康托展开及其逆运算实现 C++

    康托展开 康托展开 求一个数在其全排列的次序 规定a[n]为 在第n位后面且比其数值小的数字个数与 (n-1)! ...

  • 康托展开

    原博客 康托展开的公式是 X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+......

  • 康托展开

    康托展开用于求1~n任意排列的排名,排名是指按字典序排序后的排名。举例对于2314来说,2前面只有1比他小,开头为...

  • 康托展开公式与全排列应用

    康托展开公式 怎样知道其中一种排列是有序序列中的第几个? 康托展开. {1...n}的全排列由小到大有序,s[]为...

  • 小朋友学奥数(21):康托展开

    一、康托展开运算 把一个整数X展开成如下形式:X = an * (n - 1)! + an-1 * (n - 2)...

  • 字符串

    字符串的实现(C++实现) 实现字符串的构造及其常用的接口函数,深入掌握理解字符串的实现 C++ / STL 中s...

  • 堆及其C++实现

    堆的定义 堆是一棵节点含有比较器的完全二叉树。 堆的存储 在标准库中可以使用std::priority_queue...

  • 简单排序——幸运数字(康托展开)

    时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 262144K,其他语言524288K 一、题目内容...

  • 使用 ScopeGuard 让代码更加安全可靠

    ScopeGuard用于实现Go语言中defer的功能。其主要思想和ScopeLock类似,即利用C++栈展开机制...

  • Base64编解码及其C++实现

    title: "Base64编解码及其C++实现"date: 2021-02-08T19:54:53+08:00d...

网友评论

    本文标题:康托展开及其逆运算实现 C++

    本文链接:https://www.haomeiwen.com/subject/lhdupftx.html