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 |
Output for Sample Input |
5 10 11 100 200 0 500 1234567890 2345678901 0 4294967295 |
Case 1: 1 Case 2: 22 Case 3: 92 Case 4: 987654304 Case 5: 3825876150 |
题意:给你两个数m,n。问你在m~n之间0的个数。
这题类似lightoj1032,只不过这题是求0的个数。求0的个数一定要考虑是否是首位,我们知道0不能为第一位,所以这题在搜索上就加一个判断
条件,看一下搜索到的是否为首位。
#include <iostream> #include <cstring> using namespace std; typedef long long LL; LL dp[33][33]; LL dig[33]; LL dfs(LL x , LL cnt , LL flag , LL first) { if(x == 0) { if(first) return 1; else return cnt; } if(dp[x][cnt] != -1 && !flag && !first) return dp[x][cnt]; LL sum = 0; LL gg = flag ? dig[x] : 9; for(int i = 0 ; i <= gg ; i++) { if(first) { sum += dfs(x - 1 , cnt , i == gg && flag , first && i == 0); } else { if(i == 0) { sum += dfs(x - 1 , cnt + 1 , i == gg && flag , 0); } else { sum += dfs(x - 1 , cnt , i == gg && flag , 0); } } } if(!flag && !first) dp[x][cnt] = sum; return sum; } LL Gets(LL x) { memset(dig , 0 , sizeof(dig)); int temp = 0; if(x == 0) dig[1] = 0; while(x) { dig[++temp] = x % 10; x /= 10; } return dfs(temp , 0 , 1 , 1); } int main() { int t; cin >> t; int ans = 0; while(t--) { ans++; LL n , m; memset(dp , -1 , sizeof(dp)); cin >> n >> m; //cout << Gets(m) << ' ' << Gets(n - 1) << endl; cout << "Case " << ans << ": " << Gets(m) - Gets(n - 1) << endl; } return 0; }