codeforces 440C. One-Based Arithmetic 解题报告

题目链接:http://codeforces.com/problemset/problem/440/C

题目意思:给出一个数你,问需要用到的1来组成这个数的最少数量是多少。

     我一开始对每个数只从 “+”的方向找,也就是假设对于4873,由千位开始配1,接着从百位,然后十位,最后个位。具体过程:4444  --->  4888  ---> 4877  --->  4873。对于test 3 的72我就悲剧了。因为最少数量应该是111 - 3*11 = 78, 78 - 5*1 = 72(15个1即可);而不是11*7 = 77, 77 - 5*11 = 72(19个1)(我的方法正是后者),得不到最少数量。

     正确做法应该用搜索来做。唉~~~我对于dfs中递归总是很头痛,本来想利用人家的代码来调试(我只会用VC6调)清楚,怎么知道老是穿插一些汇编代码,调到int r1 = dfs(Abs(num-p1*ones[d]), d-1);  就看不清楚了= =......

    这个代码我只能看懂一部分,希望有能之士看明白之后可以提点提点^_^...不过也好,知道自己有什么薄弱的地方赶快弥补弥补,这个递归总是要弄明白的,先放下这道题,苦练搜索题:dfs + bfs!!!

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 const int maxn = 15 + 5;
 9 LL ones[maxn], n;
10 
11 void Init()
12 {
13     ones[0] = 1;
14     for (int i = 1; i < 16; i++)
15         ones[i] = ones[i-1] * 10 + 1;
16 }
17 
18 LL Abs(LL tmp)
19 {
20     return (tmp < 0 ? -tmp : tmp);
21 }
22 
23 LL dfs(LL num, int d)
24 {
25     if (d == 0)
26         return num;
27     int p1 = num / ones[d];
28     int p2 = p1 + 1;
29     int r1 = dfs(Abs(num-p1*ones[d]), d-1);
30     int r2 = dfs(Abs(num-p2*ones[d]), d-1);
31     return min(p1*(d+1)+r1, p2*(d+1)+r2);
32 }
33 
34 int main()
35 {
36     while (scanf("%lld", &n) != EOF)
37     {
38          Init();
39          cout << dfs(n, 15) << endl;
40     }
41     return 0;
42 }

     

 调试版(VC6)(读者请忽略)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 const int maxn = 15 + 5;
 8 __int64 ones[maxn], n;
 9 
10 void Init()
11 {
12     ones[0] = 1;
13     for (int i = 1; i < 16; i++)
14         ones[i] = ones[i-1] * 10 + 1;
15     //for (int i = 0; i < 16; i++)
16     //        cout << "ones[" << i << "] = " << ones[i] << endl;
17 }
18 
19 __int64 Min(__int64 a, __int64 b)
20 {
21     return (a > b ? b : a);
22 }
23 
24 __int64 Abs(__int64 tmp)
25 {
26     return (tmp < 0 ? -tmp : tmp);
27 }
28 
29 __int64 dfs(__int64 num, int d)
30 {
31     if (d == 0)
32         return num;
33     int p1 = num / ones[d];
34     int p2 = p1 + 1;
35     int r1 = dfs(Abs(num-p1*ones[d]), d-1);
36     int r2 = dfs(Abs(num-p2*ones[d]), d-1);
37     return Min(p1*(d+1)+r1, p2*(d+1)+r2);
38 }
39 
40 int main()
41 {
42     while (scanf("%I64d", &n) != EOF)
43     {
44          Init();
45          printf("%I64d
", dfs(n, 15));
46     }
47     return 0;
48 }
原文地址:https://www.cnblogs.com/windysai/p/3839845.html