• The Digits String


    https://ac.nowcoder.com/acm/contest/338/L

    题解:

    当n==1时,0-9填上的话,对4取余,分别是余数为0的3个,1的3个,2的2个,3的2个;

    当n==2时,因为一个数的时候有3323的余数个数分布,如果第2个填上数可以使原来的余数变成0或者保持零,那么可以填上;

    当n>=3时,还是根据前面的余数分布决定接下来可以填什么数。

    暴力递推

    #include <bits/stdc++.h>
    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<bitset>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<cmath>
    #include<list>
    #include<map>
    #include<set>
    //#define DEBUG
    #define RI register int
    using namespace std;
    typedef long long ll;
    //typedef __int128 lll;
    const int N=100000+10;
    const int MOD=2019;
    const double PI = acos(-1.0);
    const double EXP = 1E-8;
    const int INF = 0x3f3f3f3f;
    ll t,n,m,k,q,ans;
    ll a[5];
    char str;
    int main()
    {
    #ifdef DEBUG
    freopen("input.in", "r", stdin);
    //freopen("output.out", "w", stdout);
    #endif
    while(~scanf("%lld",&n)){
    memset(a,0,sizeof(a));
    a[0]=3;
    a[1]=3;
    a[2]=2;
    a[3]=2;
    for(int i=2;i<=n;i++){
    int x=a[0],y=a[1],z=a[2],t=a[3];
    a[0]=(x*3+y*2+z*2+t*3)%MOD;
    a[1]=(x*3+y*3+z*2+t*2)%MOD;
    a[2]=(x*2+y*3+z*3+t*2)%MOD;
    a[3]=(x*2+y*2+z*3+t*3)%MOD;
    }
    cout<<a[0]<<endl;
    }
    //cout << "Hello world!" << endl;
    return 0;
    }


    很明显肯定会超时。

    a数组和递推a数组的系数可以构成同一个方矩阵,那么可以通过矩阵快速幂减少时间复杂度。所求的答案就是方阵a的n-1次幂中的a[]0[0];

    矩阵快速幂

    #include <bits/stdc++.h>
    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<bitset>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<cmath>
    #include<list>
    #include<map>
    #include<set>
    //#define DEBUG
    #define RI register int
    using namespace std;
    typedef long long ll;
    //typedef __int128 lll;
    const int N=10;
    const int MOD=2019;
    const double PI = acos(-1.0);
    const double EXP = 1E-8;
    const int INF = 0x3f3f3f3f;
    ll t,n,m,k,q,ans;
    ll a[5][4]={3,3,2,2,3,3,2,2,3,3,2,2,3,3,2,2};
    ll b[5][4]={3,3,2,2,3,3,2,2,3,3,2,2,3,3,2,2};
    int tmp[N][N];
    void multi(ll a[][4],ll b[][4])
    {
    memset(tmp,0,sizeof tmp);
    for(int i=0;i<4;i++)
    for(int j=0;j<4;j++)
    for(int k=0;k<4;k++)
    tmp[i][j]=(tmp[i][j]+a[i][k]*b[k][j])%MOD;
    for(int i=0;i<4;i++)
    for(int j=0;j<4;j++)
    a[i][j]=tmp[i][j];
    }
    char str;
    int main()
    {
    #ifdef DEBUG
    freopen("input.in", "r", stdin);
    //freopen("output.out", "w", stdout);
    #endif
    while(~scanf("%lld",&n)){
    ll a[5][4]={3,3,2,2,2,3,3,2,2,2,3,3,3,2,2,3};
    ll b[5][4]={3,3,2,2,2,3,3,2,2,2,3,3,3,2,2,3};
    n--;
    while(n){
    if(n&1){
    multi(a,b);
    }
    multi(b,b);
    n/=2;
    }
    cout<<a[0][0]<<endl;
    }
    //cout << "Hello world!" << endl;
    return 0;
    }


     

  • 相关阅读:
    Leetcode 118:Pascal's Triangle 杨辉三角
    Leetcode 498:对角线遍历Diagonal Traverse(python3、java)
    Leetcode加一 (java、python3)
    Leetcode747至少是其他数字两倍的最大数
    python之爬虫(爬取.ts文件并将其合并为.MP4文件——以及一些异常的注意事项)
    杭电oj1717——小数化分数(java实现)
    杭电oj_1713——相遇周期(java实现)
    杭电oj1995——汉诺塔V(java实现)
    杭电oj 2098——分拆素数和(包含如何判断质数及优化),java实现
    杭电oj————2057(java)
  • 原文地址:https://www.cnblogs.com/DWVictor/p/10278610.html
Copyright © 2020-2023  润新知