您的位置:首页 > 其它

LightOJ - 1140 How Many Zeroes?(数位DP,有前导0)

2017-10-11 18:50 621 查看
Jimmy writes down the decimal representations of all natural numbers between and including m and n, (m ≤ n). How many zeroes will he write down?
Input
Input starts with an integer T (≤ 11000), denoting the number of test cases.
Each case contains two unsigned 32-bit integers m and n, (m ≤ n).
Output
For each case, print the case number and the number of zeroes written down by Jimmy.
Sample Input
5
10 11
100 200
0 500
1234567890 2345678901
0 4294967295
Sample Output
Case 1: 1
Case 2: 22
Case 3: 92
Case 4: 987654304
Case 5: 3825876150
题意:从l到r中,所有数字中含有的0的个数。不包括前导0解题思路:数位DP,注意判断前导0.#include<iostream>#include<deque>#include<memory.h>#include<stdio.h>#include<map>#include<string.h>#include<algorithm>#include<vector>#include<math.h>#include<stack>#include<queue>#include<set>using namespace std;typedef long long int ll;ll dp[30][30];//遍历到第i位,前面有j个0的0的个数。int dig[30];//iszero记录是否有前导0ll dfs(int pos,int zeronum,bool limit,bool iszero){if(pos==-1){if(iszero)//如果有前导0,且到了最后一位,返回1,0也算一个0return 1;elsereturn zeronum;}//记忆化搜索if(!limit && dp[pos][zeronum]!=-1&&!iszero)return dp[pos][zeronum];//循环遍历下一位的每一个数字,end记录最大能达到的数int end=limit?dig[pos]:9;ll ans=0;for(int i=0;i<=end;i++){if(iszero)ans+=dfs(pos-1,0,limit&&i==end,i==0);//当前还是不是0else{if(i==0)ans+=dfs(pos-1,zeronum+1,limit&&i==end,0);//非前导零的0要把0数加1elseans+=dfs(pos-1,zeronum,limit&&i==end,0);}}if(!limit&&!iszero)dp[pos][zeronum]=ans;return ans;}ll solve(ll x){//记录每一位int pos=0;while(x){dig[pos++]=x%10;x/=10;}return dfs(pos-1,0,1,1);}int main(){ll l,r;int t;scanf("%d",&t);for(int qqq=1;qqq<=t;qqq++){scanf("%lld%lld",&l,&r);memset(dp,-1,sizeof(dp));printf("Case %d: %lld\n",qqq,solve(r)-solve(l-1));}return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: