题目链接

https://www.lydsy.com/JudgeOnline/problem.php?id=4563

题解

题目意思=错排。

注意要写一个高精度,用错排的递推式。

代码

#include <cstdio>
#include <algorithm>

int read()
{
  int x=0,f=1;
  char ch=getchar();
  while((ch<'0')||(ch>'9'))
    {
      if(ch=='-')
        {
          f=-f;
        }
      ch=getchar();
    }
  while((ch>='0')&&(ch<='9'))
    {
      x=x*10+ch-'0';
      ch=getchar();
    }
  return x*f;
}

const int maxn=200;
const int base=10000;

struct bignum
{
  int v[maxn+10];

  bignum operator +(const bignum &other) const
  {
    bignum ans;
    ans.v[0]=std::max(v[0],other.v[0]);
    int r=0;
    for(int i=1; i<=ans.v[0]; ++i)
      {
        ans.v[i]=((i>v[0])?0:v[i])+((i>other.v[0])?0:other.v[i])+r;
        r=ans.v[i]/base;
        ans.v[i]%=base;
      }
    if(r)
      {
        ans.v[++ans.v[0]]=r;
      }
    return ans;
  }

  bignum operator *(const int &other) const
  {
    bignum ans;
    ans.v[0]=v[0];
    int r=0;
    for(int i=1; i<=ans.v[0]; ++i)
      {
        ans.v[i]=v[i]*other+r;
        r=ans.v[i]/base;
        ans.v[i]%=base;
      }
    if(r>0)
      {
        ans.v[++ans.v[0]]=r;
      }
    return ans;
  }

  int print()
  {
    printf("%d",v[v[0]]);
    for(int i=v[0]-1; i; --i)
      {
        printf("%04d",v[i]);
      }
    return 0;
  }
};

bignum f[maxn+10];

int main()
{
  int n=read();
  f[1].v[0]=0;
  f[2].v[0]=f[2].v[1]=1;
  for(int i=3; i<=n; ++i)
    {
      f[i]=(f[i-1]+f[i-2])*(i-1);
    }
  f[n].print();
  putchar('\n');
  return 0;
}