zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    [C++] 用Xcode来写C++程序[5] 函数的重载与模板
    【转】字符编码详解——彻底理解掌握编码知识,“乱码”不复存在
    【转】无法将notepad++添加到打开方式列表中的解决办法
    【转】关于启用 HTTPS 的一些经验分享
    【转】GPU 与CPU的作用协调,工作流程、GPU整合到CPU得好处
    【转】excel 末尾是0 恢复数据方法
    【转】怎么让VS2015编写的程序在XP中顺利运行
    【转】深入 Docker:容器和镜像
    【转】SSL/TLS协议运行机制的概述
    【转】C++怎么读写windows剪贴板的内容?比如说自动把一个字符串复制.
  • 原文地址:https://www.cnblogs.com/windysai/p/3839845.html
Copyright © 2011-2022 走看看