[关闭]
@sztom 2019-08-25T13:47:03.000000Z 字数 980 阅读 220

T4 题解 - 定时炸弹

Exam02


定时炸弹

题目描述

现在发现了一枚计时炸弹。 这枚计时炸弹非常神奇,它的计时数字序列从11到NN.如果当前时刻数字序列包含子序列“49”,爆炸的力量将增加一点。

现在知道数字NN, 想要知道威力的最终点。 (炸弹最开始的威力是0)

输入格式

第一行输入由整数)组成,表示测试用例数。 对于每个测试用例,将会有一个整数)作为描述。输入以文件标记的末尾终止。

输出格式

对于每个测试用例,输出指示功率的最终点的整数。

输入样例

3
1
50
500

输出样例

0
1
15

题解

思路

数位dp,用表示有长度为位的以开头的49数的个数。
有状态转移方程:

代码

  1. #include <iostream>
  2. #include <memory.h>
  3. using namespace std;
  4. int F[100][10], d[100];
  5. void init() {
  6. F[0][0] = 1;
  7. for(int i = 1; i <= 90; ++i){
  8. for(int j = 0; j <= 9; ++j){
  9. for(int k = 0; k <= 9; ++k){
  10. if (j == 4 && k == 9) continue;
  11. F[i][j] += F[i-1][k];
  12. }
  13. }
  14. }
  15. }
  16. unsigned long long f(unsigned long long x) {
  17. memset(d, 0, sizeof(d));
  18. int len = 0;
  19. unsigned long long res = 0;
  20. while (x > 0) {
  21. ++len;
  22. d[len] = x % 10;
  23. x /= 10;
  24. }
  25. for (int i = len; i >= 1; i--) {
  26. for (int j = 0; j <= d[i] - 1; ++j) {
  27. if (j == 9 && d[i+1] == 4) continue;
  28. res += F[i][j];
  29. }
  30. if (d[i] == 9 && d[i+1] == 4) break;
  31. }
  32. return res;
  33. }
  34. int main() {
  35. init();
  36. int T;
  37. unsigned long long n;
  38. cin >> T;
  39. while (T--) {
  40. cin >> n;
  41. cout << n - (f(n + 1) - f(1)) << endl;
  42. }
  43. return 0;
  44. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注