您的位置:首页 > 文旅 > 美景 > 中科宁波网站建设_网络科技公司是真是假_网站优化公司怎么选_网络推广团队

中科宁波网站建设_网络科技公司是真是假_网站优化公司怎么选_网络推广团队

2025/4/14 14:04:50 来源:https://blog.csdn.net/2401_87294509/article/details/147102325  浏览:    关键词:中科宁波网站建设_网络科技公司是真是假_网站优化公司怎么选_网络推广团队
中科宁波网站建设_网络科技公司是真是假_网站优化公司怎么选_网络推广团队

题意:

一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位……)上的数字是奇数,偶数位(十位、千位、十万位……)上的数字是偶数,我们就称之为“好数”。

给定一个正整数 N,请计算从 1 到 N 一共有多少个好数。

思路:

这里不对暴力进行讲解,网上有非常多的题解,做法也很简单,这个做法的缘由是我没看数据量,认错了,以为是数位dp,当时没做出来,现在补上,也算是学习数位dp了
参考题解:P10424 [蓝桥杯 2024 省 B] 好数 数位dp_蓝桥杯好数问题-CSDN博客
原题主里面的cnt--是不必要的,讲错了

思路其实也不难,就是标准的数位dp,这里讲解是怎么来理解这道题的数位dp的

dp[i]表示的是,当前位置之前填写最高位的这个时刻,填剩下所有可能数的大小,往后就是默认填写最高位数字的,如果不是很明白推荐  董晓老师的数位dp

1.dp[i]代表当前这一位在填写[1,3,5,7,9]或者[0,2,4,6,8](注意要小于数本身)的可能算上所有的个数,因为高位固定,低位一定能两个区间都能取的,直接预处理pre数组,进行计算就好。个数就是能填的个数xpre[i],注意不包括本身

2.为什么不包括本身,因为本身是不可直接计算的,因为你计算的话可能超过本身的数。dp那里计算的是一定能得到的所有数,所以最后有一个if,判断最后dp结束的那个数本身。

3.但这并没有结束,因为其实奇数位是能填0的,前提是高位没有任何数,所以加上最后的个数,就是答案。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
const int N = 2e5+10;
const int INF = 1e18;
const int MOD = 1e9+7;int pre[20],num[20];void solve(){int n;cin >> n;pre[1]=1;for(int i=2;i<20;i++){pre[i]=pre[i-1]*5;}int cntt=1;while(n){num[cntt++]=n%10;n/=10;}cntt--;int sum=0;for(int i=cntt;i>=0;i--){int cur=num[i];if(cur){int cnt=0;if(i&1){cnt+=cur/2;}else{cnt+=(cur+1)/2;}sum+=cnt*pre[i];}if( (i&1) != (num[i]&1) ){break;}if(i==1 && num[i]&1){sum++;}}for(int i=cntt;i>1;i--){if(i&1){sum+=pre[i];}}cout << sum << endl;}signed main() {IOS;int t = 1;
//	cin >> t;while (t--) {solve();}}


 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com