数字根(digital root)

  

  来源:LeetCode 258  Add Dights

  Question:Given a non-negative integer  num , repeatedly add all its digits until the result has only one digit.

  For example:

     Given  num = 38 , the process is like:  3 + 8 = 11 ,  1 + 1 = 2 . Since  2  has only one digit, return it.

  Follow up:
     Could you do it without any loop/recursion in O(1) runtime?

  分析

  数字根(digital root)是自然数的一种性质,即每个自然数都有一个数字根。数根是将一自然数的各个位数相加(即横向相加),若加完后的值大于等于10的话,则继续将各位数进行横向相加直到其值小于10为止。例如54817的数根为7,因为5+4+8+1+7=25,25大于10则再加一次,2+5=7,7小于10,则7为54817的数字根。

  上面问题即是求一个非负整数的数字根。很容易想到下面这种方法解决问题:

#include<stdio.h>
#include<assert.h>

int addDigits(int num)
{
    int temp=0;
    while(num>=10)
    {
        temp+=(num%10);
        num/=10;
    }
    temp+=num;        //不要忽略最高位数
    num=temp;
    if(num>=10)
    {
        num=addDigits(num);//num仍大于10,则递归调用addDights函数
    }
    return num;
}

int main()
{
    int num;
    scanf("%d",&num);
    assert(num>=0);    //非负整数断言
    printf("%d\n",addDigits(num));
    return 0;
}

  注意题目的延伸:要求我们不使用循环/递归复杂度O(1)

  这里用到一个求数字根的公式:    

             

  上述公式的文字表述为:0的数字根为0,9的倍数的数字根为9,其他自然数的数字根为其除以9的余数。证明过程点击这里

  

  上述公式可简单表述为:

  

  所以对于延伸的问题我们可以写出解决方法如下:

#include<stdio.h>
#include<assert.h>

int addDigits(int num)
{
    return 1+(num-1)%9;        //直接调用公式
}

int main()
{
    int num;
    scanf("%d",&num);
    assert(num>=0);    //非负整数断言
    printf("%d\n",addDigits(num));
    return 0;
}

  

时间: 2024-10-18 03:50:54

数字根(digital root)的相关文章

如何证明一个数的数根(digital root)就是它对9的余数?

数根就是不断地求这个数的各位数之和,直到求到个位数为止.所以数根一定和该数模9同余,但是数根又是大于零小于10的,所以数根模9的余数就是它本身,也就是说该数模9之后余数就是数根. 证明: 假设有一个n位的10进制数,我们写成,其中表示从低到高的每一位因为 那么 也就是一个数和它的各数位之和的模9相同.不如我们把这个操作记为f即也就是所以也就是说每做一次这样的操作,它对于9的模始终是不变的所以最终求出的数根和原数对9的模相同. 例子:(12345) % 9 = (1 + 2 + 3 + 4 + 5

Digital root(数根)

关于digital root可以参考维基百科,这里给出基本定义和性质. 一.定义 数字根(Digital Root)就是把一个数的各位数字相加,再将所得数的各位数字相加,直到所得数为一位数字为止.而这个一位数便是原来数字的数字根.适用范围为正整数和零.例如:65536,6+5+5+3+6=25,2+5=7,故数根为7. 二.性质 1. 任何数加减9的数字根还是它本身. 2. 9乘任何数字的数字根都是9. 3. 数字根的三则运算 (1). 两数之和的数字根等于这两个数的数字根的和数字根 (2).

HDU 1013 Digital Roots(两种方法,求数字根)

Digital Roots Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 67949    Accepted Submission(s): 21237 Problem Description The digital root of a positive integer is found by summing the digits of

zju 1115 Digital roots 数字根

#include <iostream> #include <string> using namespace std; int main() { string n; while(cin>>n,n!="0") { int s=0,l=n.length(); for(int i=0;i<l;i++) s+=n[i]-'0'; while(s>9) s=s/10+s%10; cout<<s<<endl; } return

(HDU)1013 --Digital Roots(数字根)

描述 正整数的数字根是通过对整数的数字求和得到的. 如果结果值是一个数字,那么该数字是数字根. 如果结果值包含两个或多个数字,则将这些数字相加,并重复该过程. 只要需要获得一位数字,就可以继续.例如,考虑正整数24.2和4相加产生值6.由于6是单个数字,6是24的数字根.现在考虑正整数39.3和9相加.由于12不是单个数字,所以必须重复该过程. 1和2相加得到3,3是一个单一的数字,也就是39的数字根. 输入 输入文件将包含一个正整数列表,每行一个. 输入的结束将由整数值零指示. 输出 对于输入

SGU[118] Digital Root

Description 描述 Let f(n) be a sum of digits for positive integer n. If f(n) is one-digit number then it is a digital root for n and otherwise digital root of n is equal to digital root of f(n). For example, digital root of 987 is 6. Your task is to fi

DIgital Root 的推导

背景 在LeetCode上遇到这道题:Add Digits 题目很简单,但是如果要用 O(1) 时间复杂度,不要涉及循环或递归来解答的话,我就不知道如何下手了. 于是我找了一下别人的解法,发现涉及到一个 Digital Root 的原理(由于维基百科打不开,所以我觉得有必要记录一下我搜集到的信息和理解). Digital Root 我是从这个网站上看到它的推导过程,但是为了防止以后这些引用的网站不存在或者访问不了,还是得自立更生写一下. 首先,A ≡ B mod C, ≡ 这个符号, 表示 A

ACM之数论数字根

先来看一道杭电的数字根问题 此题的大大意是输入一个数,如果它不是一位的数字的话,那么我们就将它的每一位都相加,相加后如果还是两位或者更多的话那么我们继续取出它的每一位数字进行相加,知道等到单个数字为止. 初次看到这道题,并没有看n的取值范围,便直接写了个int类型的,不一会就写出来了,测试,通过.然而呢,当我提交的时候才知道,正因为没有给出n的取值范围,所以你需要考虑大数的问题! 当然数论的题,常常包含着我们或许不知道的定理啊,什么的,毕竟像ACM之类的题,我们通常不能直接按照题目的叙述直接做,

Digital root的求解

源于hdu1013 题目描述: The digital root of a positive integer is found by summing the digits of the integer. If the resulting value is a single digit then that digit is the digital root. If the resulting value contains two or more digits, those digits are s