如何在不转换的情况下检查不在10的数字的可分性?

时间:2011-01-22 08:44:47

标签: algorithm math numbers division

假设我有一些基数3,1211。我怎么能检查这个数字是否可被2整除而不将其转换回基数10?

更新
最初的问题来自TopCoder
数字3和9共享一个有趣的属性。如果取3的任意倍数并加上其数字,则得到3的另一个倍数。例如,118 * 3 = 354和3 + 5 + 4 = 12,这是3的倍数。同样,如果你取任何倍数9和9的总和,你得到9的另一个倍数。例如,75 * 9 = 675和6 + 7 + 5 = 18,这是9的倍数。调用此属性有趣的任何数字,除了0和1,财产保持平凡。 在一个基础中感兴趣的数字在另一个基础中不一定有趣。例如,3在基数10中很有趣但在基数5中不感兴趣。给定一个int基础,你的任务是按递增顺序返回该基数的所有有趣数字。要确定某个特定数字是否有趣,您无需考虑该数字的所有倍数。您可以确定,如果该属性适用于少于四位数的所有数字的倍数,则它也适用于具有更多数字的倍数。例如,在基数10中,您不需要考虑任何大于999的倍数 备注
- 当base大于10时,数字的数值可能大于9.因为默认情况下整数显示在基数10中,所以当这些数字在屏幕上显示为超过一位十进制数字时,请不要发出警报。例如,基数16中的一个有趣数字是15 的约束
- 基数介于3至30之间。

这是我的解决方案:

class InterestingDigits {
public:
    vector<int> digits( int base ) {
        vector<int> temp;
        for( int i = 2; i <= base; ++i )
            if( base % i == 1 )
                temp.push_back( i );
        return temp;
    }
};

这里的诀窍很好解释:https://math.stackexchange.com/questions/17242/how-does-base-of-a-number-relate-to-modulos-of-its-each-individual-digit

谢谢,

5 个答案:

答案 0 :(得分:9)

如果您的数字k在三位,那么您可以将其写为

k = a0 3^n + a1 3^{n-1} + a2 3^{n-2} + ... + an 3^0

其中a0,a1,...,an是基数为三的数字。

要查看该数字是否可被2整除,您会对模数为2的数字是否等于零感兴趣。好吧,k mod 2由

给出
k mod 2 = (a0 3^n + a1 3^{n-1} + a2 3^{n-2} + ... + an 3^0) mod 2
        = (a0 3^n) mod 2 + (a1 3^{n-1}) mod 2 + ... + an (3^0) mod 2
        = (a0 mod 2) (3^n mod 2) + ... + (an mod 2) (3^0 mod 2)

这里的诀窍是3 ^ i = 1(mod 2),所以这个表达式是

k mod 2 = (a0 mod 2) + (a1 mod 2) + ... + (an mod 2)

换句话说,如果你总结三元表示的数字并得到该值可被2整除,则数字本身必须可被2整除。为了使这个更酷,因为唯一的三元数字是0,1和2,这相当于询问三元表示中的1的数量是否是偶数!

更一般地说,如果你有一个基数m的数字,那么这个数字可以被m - 1整除,如果这些数字的总和可以被m整除。这就是为什么你可以通过对数字求和并查看该值是否可被9整除来检查基数10中的数字是否可被9整除。

答案 1 :(得分:3)

您始终可以为任何基数和任何除数构建有限自动机:

通常计算基础n中一串数字的值b 你迭代数字并做

n = (n * b) + d
每个数字d

现在,如果您对可分性感兴趣,可以使用模m来代替:

n = ((n * b) + d) % m

此处n最多可以包含m个不同的值。将这些作为有限自动机的状态,并根据该公式根据数字d计算转换。接受状态是余数为0的状态。

对于您的具体情况,我们有

n == 0, d == 0: n = ((0 * 3) + 0) % 2 = 0
n == 0, d == 1: n = ((0 * 3) + 1) % 2 = 1
n == 0, d == 2: n = ((0 * 3) + 2) % 2 = 0
n == 1, d == 0: n = ((1 * 3) + 0) % 2 = 1
n == 1, d == 1: n = ((1 * 3) + 1) % 2 = 0
n == 1, d == 2: n = ((1 * 3) + 2) % 2 = 1

表示您可以将数字1模2加1并忽略任何数字0或2.

答案 2 :(得分:1)

我不确定你在什么CPU上有一个基数为3的数字,但正常的做法是执行模数/余数运算。

if (n % 2 == 0) {
    // divisible by 2, so even
} else {
    // odd
}

如何实现模数运算符将取决于您如何存储基数为3的数字。最简单的代码可能是实现普通的铅笔纸长分割,并从中得到余数。

    0 2 2 0
    _______
2 ⟌ 1 2 1 1 
    0
    ---
    1 2
    1 1
    -----
      1 1
      1 1
      -----
        0 1 <--- remainder = 1 (so odd)

(无论基数如何,这都适用于基数-3,正如其他人所提到的那样)

答案 3 :(得分:1)

将所有数字加在一起(或者甚至只计算数字) - 如果答案是奇数,则数字为奇数;如果它是均匀的,那么琥珀是均匀的。

这是如何工作的?数字中的每个数字贡献0,1或2次(1,3,9,27 ......)。 0或2加上偶数,因此对整数的奇数/偶数(奇偶校验)没有影响。 A 1加上3的幂之一,它总是奇数,因此翻转奇偶校验)。我们从0(偶数)开始。因此,通过计算翻转次数是奇数还是偶数,我们可以判断数字本身是否为。

答案 4 :(得分:1)

与基数10相同,例如: 1.找到2的倍数&lt; = 1211,即1210(见下文如何实现) 从1211中减去1210,得到1 3.1是&lt; 1。 10,因此1211不能被2整除

如何实现1210: 1.从2开始 2. 2 + 2 = 11 3. 11 + 2 = 20 4. 20 + 2 = 22 5. 22 + 2 = 101 6. 101 + 2 = 110 7. 110 + 2 = 112 8. 112 + 2 = 121 9. 121 + 2 = 200 10. 200 + 2 = 202 ... //重复,直到得到最大数字&lt; = 1211 它与基数10基本相同,只是在3而不是10上进行整理。