BZOJ 4029 [HEOI 4029] 定价 解题报告

这个题好像也是贪心的感觉。。

我们枚举 $1,5,10,50,100,\dots$ ,找出在 $[l, r]$ 内能整除它们的最小的数。

然后找到其中在荒谬值最小的情况下数值最小的那个数,

就做完了。

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 typedef long long LL;
 8 #define INF 593119681
 9  
10 int _;
11 LL l, r;
12  
13 inline LL Calc(LL x)
14 {
15     if (!~x) return INF;
16     while (x % 10 == 0) x /= 10;
17     int f = (x % 5) ? 0 : -1;
18     int res = 0;
19     for (; x; x /= 10)
20         res += 2;
21     return res + f;
22 }
23  
24 int main()
25 {
26     #ifndef ONLINE_JUDGE
27         freopen("4029.in", "r", stdin);
28         freopen("4029.out", "w", stdout);
29     #endif
30      
31     for (scanf("%d", &_); _; _ --)
32     {
33         scanf("%lld%lld", &l, &r);
34         LL best = -1, top, bot;
35         for (LL x = 1, _x = 5; x <= r; x *= 10, _x *= 10)
36         {
37             top = (l + x - 1) / x * x;
38             bot = r / x * x;
39             if (top <= bot) best = (Calc(best) < Calc(top) || (Calc(best) == Calc(top) && best < top)) ? best : top;
40             top = (l + _x - 1) / _x * _x;
41             bot = r / _x * _x;
42             if (top <= bot) best = (Calc(best) < Calc(top) || (Calc(best) == Calc(top) && best < top)) ? best : top;
43         }
44         printf("%lld\n", best);
45     }
46      
47     #ifndef ONLINE_JUDGE
48         fclose(stdin);
49         fclose(stdout);
50     #endif
51     return 0;
52 }
4029_Gromah

 

posted @ 2015-05-02 11:41  Gromah  阅读(238)  评论(0编辑  收藏  举报