SSL1377编码2

编码

概述

给你一个排列,求序号(如1 2 3 4为1,5 4 3 2 1为120)

输入样例

3 2 1 4

输出样例

15

思路

就是一个康托展开,但是要加高精度,而且康托展开是从0开始编,所以错了3次555
康托展开:
公式如下:
s = a [ n ] ∗ ( n − 1 ) ! + a [ n − 1 ] ∗ ( n − 2 ) ! … … a [ 1 ] ∗ ( n − n ) ! s=a[n]*(n-1)!+a[n-1]*(n-2)!……a[1]*(n-n)! s=a[n](n1)!+a[n1](n2)!a[1](nn)!
上正确代码:

#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<map>
#include<string>
using namespace std;
bool b[60];
int a[60],n;
int q[1001],q2[1001];
string add(string a,string b)
{
 memset(q,0,sizeof(q));
 memset(q2,0,sizeof(q2));
 for (int i=1;i<=a.size();i++) q[i]=a[a.size()-i]-'0';
 for (int j=1;j<=b.size();j++) q2[j]=b[b.size()-j]-'0';
 int s=0,g=0;
 for (int i=1;i<=1000;i++)
 {
  s=q[i]+q2[i]+g;
  q[i]=s%10;
  g=s/10;
 }
 int i=1000;
 while (i>1&&q[i]==0) i--;
 string y="";
 for (int j=i;j>=1;j--)
 {
  char x=q[j]+'0';
  y+=x;
 }
 return y;
}
string divb(string x,int y)
{
 string c1="";
 unsigned long long u=0;
 for (int i=0;i<x.size();i++)
 {
  u=u*10+x[i]-'0';
  char x=u/y+'0';
  c1+=x;
  u%=y;
 }
 while (c1[0]=='0') c1.erase(0,1);
 return c1;
}
string mul(string a,int b)
{
 memset(q,0,sizeof(q));
 for (int i=1;i<=a.size();i++) q[i]=a[a.size()-i]-'0';
 int s=0,g=0;
 for (int i=1;i<=1000;i++)
 {
  s=q[i]*b+g;
  q[i]=s%10;
  g=s/10;
 }
 int i=1000;
 while (i>1&&q[i]==0) i--;
 string y="";
 for (int j=i;j>=1;j--)
 {
  char x=q[j]+'0';
  y+=x;
 }
 return y;
}
int main()
{
 string gy;
 getline(cin,gy);
 int u=0;
 string s="1",ans="0";
 for (int i=0;i<gy.size();i++)
 {
  if (gy[i]==' ')
  {
   a[++n]=u;
   u=0;
  }
  else
  {
   u=u*10+gy[i]-'0';
  }
 }
 a[++n]=u;
 for (int i=1;i<=n;i++) s=mul(s,i);
 for (int i=1;i<=n;i++)
 {
  u=0;
  for (int j=1;j<a[i];j++)
  {
   if (b[j]==0) u++;
  }
  b[a[i]]=1;
  s=divb(s,n-i+1);
  ans=add(ans,mul(s,u));
 }
 cout<<add(ans,"1");
 return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值