寒假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
题意:
如果一个整数符合下面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~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」