zoukankan      html  css  js  c++  java
  • 寒假Day30:HDU4507吉哥系列故事恨7不成妻数位dp

    题面:

    单身!
      依然单身!
      吉哥依然单身!
      DS级码农吉哥依然单身!
      所以,他生平最恨情人节,不管是214还是77,他都讨厌!
      
      吉哥观察了214和77这两个数,发现:
      2+1+4=7
      7+7=7*2
      77=7*11
      最终,他发现原来这一切归根到底都是因为和7有关!所以,他现在甚至讨厌一切和7有关的数!
    
      什么样的数和7有关呢?
    
      如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关——
      1、整数中某一位是7;
      2、整数的每一位加起来的和是7的整数倍;
      3、这个整数是7的整数倍;
    
      现在问题来了:吉哥想知道在一定区间内和7无关的数字的平方和。
    Input
    输入数据的第一行是case数T(1 <= T <= 50),然后接下来的T行表示T个case;每个case在一行内包含两个正整数L, R(1 <= L <= R <= 10^18)。
    Output
    请计算[L,R]中和7无关的数字的平方和,并将结果对10^9 + 7 求模后输出。
    Sample Input
    3
    1 9
    10 11
    17 17
    Sample Output
    236
    221
    0
    View Code

    题意:

      如果一个整数符合下面3个条件之一,则和7有关
      1、整数中某一位是7;
      2、整数的每一位加起来的和是7的整数倍;
      3、这个整数是7的整数倍;

      求给定区间内和7无关的数字的平方和。

    https://blog.csdn.net/Estia_/article/details/83479031

    这个博客的思路写的清楚倒挺好的,但是这个代码里面的结构体里面的结构体我没看懂,,

    代码:

    #include<string.h>
    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const ll mod=1e9+7;
    
    struct node
    {
        ll cnt;//某一位是7
        ll sum;//每一位加起来的和是7的整数倍
        ll sqsum;//本身是七的整数倍
    } dp[20][10][10];
    
    int digit[25];
    ll p[25];
    
    void init()
    {
        p[0]=1;
        for(int i=1; i<20; i++)
            p[i]=(p[i-1]*10)%mod;
        //如何给结构体中某一属性赋值??
    //    for(int i=0; i<20; i++)
    //    {
    //        for(int j=0; j<10; j++)
    //        {
    //            for(int k=0; k<10; k++)
    //            {
    //                dp[i][j][k].cnt=-1;
    //            }
    //        }
    //    }
    }
    
    node dfs(int len,int p1,int p2,bool limit)
    {
        if(len==-1)
        {
            node pp;
            pp.cnt=(p1!=0&&p2!=0);
            pp.sum=pp.sqsum=0;
            return pp;
            // return 1;
        }
        if(limit==0&&dp[len][p1][p2].cnt)
            //if(limit==0&&dp[len][p1][p2].cnt!=-1)//并且当前的数位已经统计过
            return dp[len][p1][p2];
        ll up;
        if(limit==1)
            up=digit[len];
        else
            up=9;
        node pp,qq;//为什么不能集体定义????WA??
        qq.cnt=qq.sqsum=qq.sum=0;
        for (int i=0; i<=up; i++)
        {
            if(i==7)
                continue;
            pp=dfs(len-1,(p1+i)%7,(p2*10+i)%7,limit&&i==up);
            qq.cnt+=pp.cnt;
            qq.cnt%=mod;
    
            qq.sum+=(pp.sum+((p[len]*i)%mod)*pp.cnt%mod)%mod;
            qq.sum%=mod;
    
            qq.sqsum+=(pp.sqsum+((2*p[len]*i)%mod)*pp.sum)%mod;
            qq.sqsum%=mod;
            qq.sqsum+=(pp.cnt*p[len])%mod*p[len]%mod*i*i%mod;
            qq.sqsum%=mod;
        }
        if (limit==0)//是一个完整的状态,等到下一次dfs的时候可以直接返回
            dp[len][p1][p2]=qq;
        return qq;
    }
    
    ll solve(ll x)
    {
        int num=0;//有多少个数位
        while(x)
        {
            digit[num++]=x%10;
    //不知道为什么这一题++num就不对了
            x/=10;
        }
        return dfs(num-1,0,0,1).sqsum;//从高位,从上面往下面遍历
    }
    
    int main()
    {
    //    memset(dp,0,sizeof(dp));//数位dp貌似清空-1需要清一次、清空二为0则不需要写清空语句
        init();
        int t;
        cin>>t;
        while(t--)
        {
            ll l,r;
            cin>>l>>r;//定义成int会WA
            ll ans=solve(r)-solve(l-1);
            ans=(ans%mod+mod)%mod;//防止为负
            cout<<ans<<endl;
            //cout<<n+1-solve(n)<<endl;
            // 给了上下界cout<<solve(m)-solve(n-1)<<endl;
        }
        return 0;
    }

    待解决:

    一些需要解决的问题都记录在上下文了,我已经不想看这一道题了

    thinking:

    这道题我改了几个小时???

    本来还要下午写完看英语,然后,,,,写到现在还没写完,

    真的是补了一天题,,,太菜了实在是,,恨铁不成刚啊,

    为什么里面的node非要重新定义,不影响啊???

    里面的cnt清不清或者清-1都没有影响

    我要原地爆炸了

    英语还没看,boom~

  • 相关阅读:
    POJ2182Lost Cows
    BZOJ4003: [JLOI2015]城池攻占
    POJ1635Subway tree systems
    BZOJ1005: [HNOI2008]明明的烦恼
    POJ1182 NOI2001 食物链
    栈的链式实现
    栈的数组实现
    链表ADT的实现
    #ifndef的用法
    using namespace std
  • 原文地址:https://www.cnblogs.com/OFSHK/p/12319647.html
Copyright © 2011-2022 走看看