计算从1到N的整数1的总数

时间:2016-02-06 18:23:46

标签: algorithm math

问题陈述:

给定整数n,计算出小于或等于n的所有非负整数中出现的数字1的总数。

例如: 给定n = 13, 返回6,因为数字1出现在以下数字中:1,10,11,12,13。

高效解决方案:

  location= location.split(' ').map(_.capitalize).mkString(" ")

我的问题:

我在其中一个论坛找到了问题的解决方案,我发现很难理解解决方案。我理解它非常简单,但请详细解释请帮助我。

谢谢

3 个答案:

答案 0 :(得分:1)

因此,在您的问题中包含的代码中,digit正在从右到左移动数字,而qx的数量相对应,增加了10的幂,都在数量上。 while循环中的每个循环计算该位置中有多少个循环。让我们看一个例子:

n     => 131
digit =>  1,  3,  1
q     => 13,  1,  0
x     =>  1, 10,100

q * x      => 13*1
// there are 13 ones in the 10^0 position from 0 to 130 (13 counts of 10)

digit == 1 => n % 1 + 1 = 0 + 1 = 1
// there is 1 one in the 10^0 position from 131 to 131 
   (the remainder for the counts of 10)

---

q * x      => 1*10
// there are 10 ones in the 10^1 position from 0 to 100 (1 count of 100): 10 to 19

digit == 3 => x = 10
// there are 10 ones in the 10^1 position from 101 to 131: 110 to 119
   (the remainder for the counts of 100)

---

q * x      => 0*100
// there are 0 ones in the 10^2 position from 0 to 0 (0 counts of 1000)

digit == 1 => n % 100 + 1 = 31 + 1
// there are 32 ones in the 10^2 position from 0 to 131
   (the remainder for the counts of 1000)

答案 1 :(得分:0)

以下是解决此问题的一种方法:假设n < 10^k,即n可由k十进制数字表示。让我们尝试构造所有具有k或更少十进制数字的正数,其中包含1个。 将2^k放入某些1位中有k种可能性。

对于每个1展示位置的选择,我们可以轻松统计所有最多k位且且小于n的正数。

例如,与yxxx1xx11x模式匹配的所有数字,x可以是02-9y 2-9 }。请注意那里的特殊y,因为如果y==0,则x之后的8 * 9^6不允许为零。有3 * 8 * 9^6种可能性。因此,此模式会为总计数提供1,因为每个此类数字包含3 n个。

这有点复杂,因为我们需要将数量限制为小于或等于y的数字。这意味着并非xn=6239914230的每个组合都有效。例如,如果y<=6y<6x,则第一个{{1}}必须最多为2,等等......

答案 2 :(得分:0)

尝试在此处观察模式

考虑N = 2196,它有4位数字,位数分别为数十,数百和数千。

现在,尝试观察模式:

Numbers having 1 at ones position
1  11  21  31  41  51  ...

Numbers having 1 at tens position
10  110  210  310  ...
11  111  211  311  ...
......................
19  119  219  319  ...

Numbers having 1 at hundreds position
100  1100  2100  ...
101  1101  2101  ...
102  1102  2102  ...
....................
199  1199  2199  ...

您能看到一个由1个数字组成的集群,其周期为10的情况吗? 一个10个数字的簇,其时间周期为十以百计,一个100个数字的簇,时间周期为百以千计? 因此,我们的最终答案将是Summation of (N / Time Period) * Cluster Size 但是,请注意最后一种情况 如果N % Time Period != 0,则还有一个集群将不完整。 尝试通过取N = 2196来弄清楚。 根据以上分析:

这是C ++代码

int solve(int A){
    int ans = 0;
    for(int i = 1; i <= A; i *= 10){
        // i is cluster size.
        // temp is time period.
        int temp = i * 10;
        // min(max(A%temp-i+1, 0), i) -> this part is going to take care 
        // of extra last cluster.
        ans += ((A/temp) * i) + min(max(A%temp-i+1, 0), i);
    }
    return ans;
}
相关问题