由一点的猜想(附)

首次验证小数字代码

#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std ;
const int maxn = 101;
#define ll unsigned long long
inline ll A (int n)
{
    ll x = 1 ;
    for(int i = 2 ; i <= n ; ++ i)
        x = (ll)i * x ;
    return x ;
}
inline ll C (int n , int m)
{
    if(m > n-m)
        return C(n,n-m);
    ll x = 1 ;
    for(int i = 1 ; i <= m ; ++ i)
        x = (x * (ll)(n-i+1)) / (ll)i ;
    return x ;
}
ll a[maxn]={0,0,1};
int main(){
    for(int i = 2; i <= maxn-1 ; ++ i){
        a[i] = A(i) - 1;
        for(int j = 1 ; j <= i; ++ j){
            a[i] -= C(i,j)*a[i-j];
        }
        if(a[i] == (a[i-1]+a[i-2])*(i-1));
        else {
            printf("%d\n",a[i]);
            return 0;   
        }
    } 
}

为了进一步验证,学习了同余之后,在同余的情况下进一步验证
第二次挑战时间复杂度内的验证代码

#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std ;
const int maxn = 1001;
const int mod = 1e6+7;
//因排列数和组合数太大,所以在同余下进行 
int Alast = 2 ;
//因为前两个数直接给出,所以下面从3开始,给出了2的全排列 
inline int A (int n){
    return Alast = (Alast * n) % mod ;
}
inline int C (int n , int m){
//因为测试范围不大,就没有用乘法逆元求 
    if(m > n-m)
        return C(n,n-m);
    int x = 1 ;
    for(int i = 1 ; i <= m ; ++ i)
        x = ((x * (n-i+1)) / i) % mod ;
    return x ;
}
int a[maxn]={0,0,1};
inline int cal(int n){
    int x = (A(n) + mod - 1) % mod ;
    for(int i = 1 ; i <= n ; ++ i)
        x = (x + mod - (C(n,i)*a[n-i]) % mod) % mod ;
    return x;
}
int main(){
    for(int i = 3 ; i <= maxn-1 ; ++ i)
        if((a[i] = cal(i)) != ((a[i-1]+a[i-2])%mod)*(i-1) % mod){
            printf("%d\n",i);
            return 0;   
        }
    return 0 ;
}

猜你喜欢

转载自www.cnblogs.com/-charon/p/12436002.html