I00025 寻找循环数

这个程序为《数学之美系列程序》之一。

这个问题是:找出所有n位数中的循环数。

一个n位数中的循环数是指该数乘以1到n之后,每位数字顺序发生移位,可以是移动若干位。

例如:142857是一个6位数的循环数,满足以下条件:
142857*1=142857
142857*2=285714
142857*3=428571
142857*4=571428
142857*5=714285
142857*6=857142

经过试算,这样的数并不好找,1到6位数中只有这一个。

给出的程序是按照自顶向下逐步细化的编程方法编写的顺序程序。对于程序员来说这样的编程训练是必要的,毕竟编写顺序程序是常有的事情。

程序如下:

/* 找出所有n位数中的循环数,该数乘以1到n的数后,每位数字顺序发生移位,可以是移动若干位。
 *
 * 例如:142857是一个6位数的循环数,满足以下条件:
 * 142857*1=142857
 * 142857*2=285714
 * 142857*3=428571
 * 142857*4=571428
 * 142857*5=714285
 * 142857*6=857142
 *
 */

#include <stdio.h>

// 判定n位数v乘以r是否为循环数,变量gethighdigit用于获取v的最高位
int isCycle(int v, int n, int r, int gethighdigit)
{
    int t, i, highdigit;

    t = v * r;

    // 乘积有进位则不是循环数
    if(t / gethighdigit / 10 > 0)
        return 0;

    // 把最高位循环移位到最低位
    for(i=1; i<=n; i++) {
        // 取出最高位
        highdigit = t / gethighdigit;
        // 计算循环移位结果
        t = t % gethighdigit * 10 + highdigit;

        // 循环移位后,某个数是原数的循环移位结果,则该数乘以r为循环数
        if(t == v)
            return 1;
    }

    // 所有的循环移位都不是循环数,则原数不是循环数
    return 0;
}

// 判定n位数v是否为循环数
int isCycleNumber(int v, int n)
{
    int i, gethighdigit=1;

    // 计算用于取最高位的数
    for(i=1; i<n; i++)
        gethighdigit *= 10;

    // 乘以2到n的数,有一个不是循环数则该数不是循环数
    for(i=2; i<=n; i++)
        if(!isCycle(v, n, i, gethighdigit))
            return 0;

    // 乘以2到n的数,都是循环数,则该数是循环数
    return 1;
}

int main(void)
{
    int n, start=1, end=9, i, j;

    // 输入n
    scanf("%d", &n);

    // 计算n位数的最小值start和最大值end
    for(i=1; i<n; i++) {
        start *= 10;
        end *= 10;
        end += 9;
    }

    // 对所有的n位数,判定该数是否为循环数,若为循环数则输出
    for(i=start; i<=end; i++)
        if(isCycleNumber(i, n)) {
            printf("%d
", i);
            for(j=1; j<=n; j++)
                printf("%d*%d=%d
", i, j, i*j);
        }

    return 0;
}

输入6时,程序执行结果如下:

6
142857
142857*1=142857
142857*2=285714
142857*3=428571
142857*4=571428
142857*5=714285
142857*6=857142


原文地址:https://www.cnblogs.com/tigerisland/p/7564761.html