查找制作给定数字所需的最小位数

时间:2020-08-08 08:16:08

标签: c++ c++14

我们必须找到一个给定数字所需的最小位数,例如:14 => 95(9 + 5 = 14)是两位,是形成14的最小值。

int moves(int n) {

    int m = 0;            // Minimum count

    while (n-9 >= 0) {    // To place maximum number of 9's
        n -= 9;
        m++;
    }

    if (n == 0) {         // If only nines made up the number
        return m;
    }

    else {
        m++;
        return m;
    }
}

我获得了在线法官的TLE(超过了运行时间限制)。我该如何改善或有更好的方法?

4 个答案:

答案 0 :(得分:7)

您的代码首先查看9适合该数字的次数。这可以更轻松地完成:

int m = n/9;

这足够了,因为我们进行整数除法,其中余数被丢弃。请注意,如果nfloat或其他浮动类型,则此方法将无效。

剩下的问题是它是否可以被9整除。如果没有,我们还有一位数字。可以由模运算符完成(为了便于理解,使其变得冗长):

bool divisible_by_nine = (n % 9 == 0);

假设您可能不知道模运算符,它将返回整数除法的余数,即47%9 = 2,因为47/9 = 5余数2。

没有它,你会选择

int remainder = n - 9*m;
bool divisible = (remainder == 0);

组合:

int required_digits(int number)
{
   bool divisible = (number % 9 == 0);
   return number/9 + (divisible ? 0 : 1);
}

或在一行中,具体取决于您希望它的详细程度:

int required_digits(int number)
{
   return number/9 + (number % 9 == 0 ? 0 : 1);
}

由于没有任何循环,因此它在Θ(1)中,因此应在您要求的时间限制内工作。

(从技术上讲,处理器可能会像您在内部一样处理除法,但是这样做非常有效。要绝对正确,我必须添加“假设除法是恒定时间的操作”。 )

答案 1 :(得分:6)

您的解决方案工作正常。您可以尝试较短的代码:

return (n%9==0)? n/9 : n/9 +1 ;

更短,但不易读...

或妥协:

if (n%9==0) // n can be divided by 9
   return n/9;
else
   return n/9+1;

答案 2 :(得分:2)

说明

我们知道每个数字img = Image.open(image_bytes).convert("RGBA") 都可以表示为 a 其中(a_n * 10 ^ n) + ... + (a_2 * 10 ^ 2) + (a_1 * 10) + (a_0)是数字

a_k(n位数字1)。

意思是数字10 ^ n可以表示为11 ... 11 +1个数字的总和。

现在我们可以将10^n = 11...11 * 9 + 1写为a

按9分组后(帮助,我对此不知道英文术语。分解吗?(a_n * 11..11 * 9 + a_n) + ... 我将其写为(a_n * 11..11 + a_n-1 * 11..11 + ... a_1) * 9 + (a_n + a_n-1 + ... + a_1 + a_0)

这意味着数字b_9 * 9 + b_1可以表示为a数字9的总和+ b_9需要多少(顺便递归)

要概括:

让我们调用函数f

  • 如果-10

  • 需要两个计数器b_1c1

  • 迭代数字

  • 对于第c2位数字,乘以i位数字11..11,并将结果添加到i

  • 将第c1位数字添加到i

  • 结果为c2

为了实践,请以非递归的方式实现。

答案 3 :(得分:0)

您猜想,您需要将一个较小的数字迭代到一个较大的数字,例如111119很好,但是我们想要最低的数字...您的答案是错误的。最低的是59!

您可以蛮力地使用它,但是它会起作用,但是对于更大的数字,您会遇到困难,因此您首先需要猜测:我需要找到多少个最小位数?

例如,如果要查找42,只需添加9,就需要使结果溢出! 9 + 9 + 9 + 9 + 9 =45。发现溢出时,您知道答案低于99999。

现在我需要减少多少才能得到正确的答案,如预期的那样3?

因此99996、99969等将是有效的!但是您想要降低,因此必须降低最大单位(当然是左侧的单位!)。

答案将是69999 = 42!

int n = 14;
int r = 0;

for (int i = i; i < 10 /*if you play with long or long long*/; i++)
   if (i * 9 >= n)
   {
       for (int j = 0; j < i; j++)
           r = r * 10 + 9;
       while (is_correct(r, n) == false)
       {
           // Code it yourself!!
       }
       return (r);
   }

现在,它可以正确返回true或false。您可以使它返回r实际减少的数字,您需要减少的数字!这不是最快的方法,而且总会有一种更快的方法,带有二进制移位,但是这种算法可以正常工作!