51nod 1035 最长的循环节 数学

1035 最长的循环节

题目连接:

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1035

Description

正整数k的倒数1/k,写为10进制的小数如果为无限循环小数,则存在一个循环节,求<=n的数中,倒数循环节长度最长的那个数。

1/6= 0.1(6) 循环节长度为1
1/7= 0.(142857) 循环节长度为6
1/9= 0.(1) 循环节长度为1

Input

输入n(10 <= n <= 1000)

Output

输出<=n的数中倒数循环节长度最长的那个数

Sample Input

10

Sample Output

7

Hint

题意

题解:

推荐一篇科普性的论文:http://w3.math.sinica.edu.tw/math_media/d253/25311.pdf

补充一下,这道题最后要求解一个 10x≡1(modC) 这个玩意儿

如果gcd(10,C)!=1的话,显然无解。

如果存在解的话,根据欧拉公式,那么这个解 x|phi(C),所以直接暴力枚举x就好了。

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1005;
long long phi[maxn];
int n;
int gcd(int a,int b)
{
    if(b==0)return a;
    return gcd(b,a%b);
}
long long quickpow(long long  m,long long n,long long k)//返回m^n%k
{
    long long b = 1;
    while (n > 0)
    {
          if (n & 1)
             b = (b*m)%k;
          n = n >> 1 ;
          m = (m*m)%k;
    }
    return b;
}
void phi1()
{
    memset(phi,0,sizeof(phi));
    phi[1]=1;
    for(long long i=2;i<=n;i++)
    {
        if(!phi[i])
        {
            for(long long j=i;j<=n;j+=i)
            {
                if(!phi[j]) phi[j]=j;
                phi[j]=phi[j]/i*(i-1);
            }
        }
    }
}
int solve(int x)
{
    for(int i=1;i*i<=phi[x];i++)
    {
        if(phi[x]%i==0)
        {
            if(quickpow(10,i,x)==1)
                return i;
        }
    }
    for(int i=sqrt(phi[x]);i>=1;i--)
    {
        if(phi[x]%i==0)
        {
            if(quickpow(10,phi[x]/i,x)==1)
                return phi[x]/i;
        }
    }
    return -1;
}
int main()
{
    scanf("%d",&n);
    phi1();
    int ans1 = 0,ans2 = 0;
    for(int i=1;i<=n;i++)
    {
        int C = solve(i);
        if(ans2<C)
            ans2 = C,ans1 = i;
    }
    cout<<ans1<<endl;
}
posted @ 2016-04-19 22:24  qscqesze  阅读(678)  评论(0编辑  收藏  举报