Cyclic Number 资料

全文资料来自wiki:http://en.wikipedia.org/wiki/Cyclic_number

Cyclic number

 Cyclic Number 是一个整数是,且其连续的倍数 (1,2,..,L-1) ,是其本身数字的一个循环。 常见的如下

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

而形如下非连续的倍数不是

076923 × 1 = 076923
076923 × 3 = 230769
076923 × 4 = 307692
076923 × 9 = 692307
076923 × 10 = 769230
076923 × 12 = 923076

若不允许前导0,则十进制下,仅有一个Cyclic Number, 142857

相关重复小数

Cyclic Number与单位分数(其小数形式重复片段)相关,长度为L的Cyclic Number可以表现为一下形式: 1 / (L+1)

相反的,如果 1/p (p是质数)  的重复片段是 p-1, 那么这个数字 p-1,就代表着一个 Cyclic Number.

例如   1/7 = 0.142857 142857….  其连续倍数如下:

1/7 = 0.142857 1428572/7 = 0.285714 2857143/7 = 0.428571 4285714/7 = 0.571428 5714285/7 = 0.714285 7142856/7 = 0.857142 857142….

Cyclic Number的形式 

  从上面单位分数形式,得到如下形式: \frac{b^{p-1}-1}{p}       其中b是进制,p是素数,且 b%p != 0 .

  不是所有的素数p都能通过以上形式产生 Cyclic Number, 例如 p=13 gives 076923076923, 会出现多个循环。

构造Cyclic Number 

伪代码如下:

Let b be the number base (10 for decimal)
Let p be a prime that does not divide b.
Let t = 0.
Let r = 1.
Let n = 0.
loop:
Let t = t + 1
Let x = r · b
Let d = int(x / p)
Let r = x mod p
Let n = n · b + d
If r ≠ 1 then repeat the loop.
if t = p − 1 then n is a cyclic number.

此程序是通过计算 b进制下的Cyclic Number  1/p . 其中r是每一步的剩余系,d是当前步的产生数,当前值为 n = n*b + d.

注意,若 t > p/2, 则这个数必定为 Cyclic Number, 无需继续计算后面部分了。

当 b 为完全平方数时,不存在长度超过1的Cyclic Number.

 

推荐训练题: http://www.codeforces.com/problemset/problem/303/D

用以上方法写的代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

typedef long long LL;

bool IsPrime(int x){
    for(int i = 2; i*i <= x; i++)
        if(x%i == 0) return false;
    return true;
}
int main(){
    int L, x, p;
    scanf("%d%d", &L, &x);
    p = L+1;
    if( (x == 2) || !IsPrime(p) ){
        puts("-1"); return 0;        
    }
    for(int b = x-1; b > 1; b--){
        if( b%p == 0 ) continue;
        LL t = 0, r = 1, n = 0, x, d;
        while(1){
            t = t+1; x = r*b; d = x/p; r = x%p; 
            n = n*b + d;
            if( r == 1 ) break;
            if( t > p/2 ){ printf("%d\n",b); return 0; }    
        }
        if( t == L ){ printf("%d\n",b);return 0; }    
    }        
    puts("-1");    
    return 0;
}
View Code

 

posted @ 2013-05-14 10:56  yefeng1627  阅读(285)  评论(0编辑  收藏  举报

Launch CodeCogs Equation Editor