zoj 3950 how many nines

https://vjudge.net/problem/ZOJ-3950

题意:

给出两个日期,计算从第一个日期开始到第二个日期,每一天的日期中的9加起来一共有多少个。

思路:

看题解补的题。首先看这题的数据量,样例就有10的5次方个,而且那只能考虑O(1)的算法喽,那么就对日期进行一个大的预处理。把从2000,1,1到10000,1,1的显示的9全部算出来,然后查询的时候直接相减,每次查询只有O(1)的复杂度。具体还是看代码啦。

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 int sum[10005][15][35],pre[10005][15][35];
 5 int mon[15] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
 6 
 7 
 8 int leap(int x)
 9 {
10     if (x % 400 == 0) return 1;
11     if (x % 100 == 0) return 0;
12     if (x % 4 == 0) return 1;
13 
14     return 0;
15 }
16 
17 int check(int y,int m,int d)
18 {
19     int num = 0;
20 
21     while (y)
22     {
23         y % 10 == 9 ? ++num : num += 0;
24         y /= 10;
25     }
26 
27     while (m)
28     {
29         m % 10 == 9 ? ++num : num += 0;
30         m /= 10;
31     }
32 
33     while (d)
34     {
35         d % 10 == 9 ? ++num : num += 0;
36         d /= 10;
37     }
38 
39     return num;
40 }
41 
42 void init(int y1,int m1,int d1,int y2,int m2,int d2)
43 {
44     int tmp = 0;
45 
46 
47     while (y1 != y2 || m1 != m2 || d1 != d2)
48     {
49         mon[2] = leap(y1) + 28;
50 
51         pre[y1][m1][d1] = tmp;//tmp是到前一个日期显示的9的数量。
52 
53         tmp += check(y1,m1,d1);
54 
55         sum[y1][m1][d1] = tmp;//现在的日期显示的9的数量
56 
57         if (++d1 > mon[m1])
58         {
59             d1 = 1;
60 
61             if (++m1 > 12)
62             {
63                 m1 = 1;
64                 mon[2] = 28 + leap(++y1);
65             }
66         }
67     }
68 }
69 
70 int main()
71 {
72     int t;
73 
74     scanf("%d",&t);
75 
76     init(2000,1,1,10000,1,1);
77 
78     while (t--)
79     {
80         int y1,m1,d1,y2,m2,d2;
81 
82         scanf("%d%d%d%d%d%d",&y1,&m1,&d1,&y2,&m2,&d2);
83 
84         printf("%d\n",sum[y2][m2][d2] - pre[y1][m1][d1]);//结束日期减去开始日期之前的那天,因为开始日期也要算的。
85     }
86 
87     return 0;
88 }

 

转载于:https://www.cnblogs.com/kickit/p/7229943.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值