zoukankan      html  css  js  c++  java
  • E. Count The Blocks

    E. Count The Blocks

    这是一个计数题,又把我卡自闭了。。。之前也碰到过类似的题目,这次居然还没有写出来,感觉自己还是太菜了,加油补题吧。

    题目大意:

    给你一个数字 (n),代表的是数的长度,该数可以有前导零,定义连续相同的数可以组成一个块,如果有 (x) 个连续相同的数,则认为这个块大小是 (x)

    问:有n个数字的这个数,可以组成大小为 (i) 的块的数量是多少。

    答案输出一行 (n) 个数,第 (i) 个数表示大小为 (i) 的块的数量。

    题解:

    这种题目就很容易把自己绕进去,所以我们不要每一个去仔细推,而是思考:我要构造大小为 (i) 的块,应该如何去构造。

    是不是选一块大小为 (i) 的块,然后这个块如果在中间,则两边的数字应该不同,其他的块则无所谓,如果在边界,则只要满足一边的数字和这个块不同即可,然后统计答案。

    这个会不会出现重复呢?或者会不会少统计了呢?

    这两个看起来有矛盾的提问,其实就解决了这两个问题。

    因为我每一个位置只统计了一次,但是可能我假设的这个位置出现大小为 (i) 的块不止一个,所以才会有疑问会不会少统计了。

    同时因为每一个位置都统计了一次,所以可能会有两个位置,出现大小为 (i) 的块的数量及位置都相同,所以才会有疑问会不会重复统计了。

    确实有可能会出现 (x) 个位置,此时出现大小为 (i) 的块的数量及位置都相同,但是每一次我只统计了一次,并没有乘以 (x) 这个数,所以不会重复,也不会丢掉一些数。

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    const int maxn=2e5+10;
    const int mod=998244353;
    typedef long long ll;
    ll dp[maxn];
    ll binpow(ll x,ll n){
        ll ans=1;
        while(n){
            if(n&1) ans=(ans*x)%mod;
            x=(x*x)%mod;
            n>>=1;
        }
        return ans;
    }
    int main(){
        int n;
        scanf("%d",&n);
        dp[n]=10,dp[n-1]=180;
        for(int i=n-2;i>=1;i--){
            dp[i]=10*9*binpow(10,n-i-1)%mod*2%mod;
    //        printf("dp[%d]=%lld
    ",i,dp[i]);
        }
        for(int i=n-2;i>=1;i--){
            dp[i]=(dp[i]+10*9*9*binpow(10,n-i-2)%mod*(n-i-1)%mod)%mod;
        }
        for(int i=1;i<=n;i++) printf("%lld ",dp[i]);
        return 0;
    }
    
  • 相关阅读:
    Python之路,day16-Python基础
    Python之路,day15-Python基础
    Python之路,day14-Python基础
    django之model操作
    django信号
    django缓存
    CSRF的攻击与防范
    cookie和session
    http协议之Request Headers
    ajax参数详解
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/12558099.html
Copyright © 2011-2022 走看看