欧拉计划 发表于 2015-4-23 16:40:50

题目26:找出小于1000的数字中令1/d拥有最长循环圈的数字d

本帖最后由 永恒的蓝色梦想 于 2020-6-14 12:34 编辑

Reciprocal cycles

A unit fraction contains 1 in the numerator. The decimal representation of the unit fractions with denominators 2 to 10 are given:

1/2      =         0.5
1/3      =         0.(3)
1/4      =         0.25
1/5      =         0.2
1/6      =         0.1(6)
1/7      =         0.(142857)
1/8      =         0.125
1/9      =         0.(1)
1/10      =         0.1
Where 0.1(6) means 0.166666..., and has a 1-digit recurring cycle. It can be seen that 1/7 has a 6-digit recurring cycle.

Find the value of d < 1000 for which 1/d contains the longest recurring cycle in its decimal fraction part.
题目:

分子为1的分数称为单分数。分母是 2 到 10 的单分数用十进制表示如下:

1/2      =      0.5
1/3      =      0.(3)
1/4      =      0.25
1/5      =      0.2
1/6      =      0.1(6)
1/7      =      0.(142857)
1/8      =      0.125
1/9      =      0.(1)
1/10      =      0.1

其中 0.1(6) 表示 0.166666...,因此它有一个长度为 1 的循环圈。可以看出 1/7 拥有一个 6 位的循环圈。

找出小于 1000 的数字 d,1/d 的十进制表示含有最长的循环圈。

愤怒的大头菇 发表于 2016-8-31 17:58:06

def func(x):
      list1 = []
      temp = 10%x
      list1.append(temp)
      while True:
            if (temp *10)%x == 0:
                  length = 0
                  break
                  
            elif (temp *10) %x not in list1:
                  temp = (temp *10) %x
                  list1.append(temp)
            elif temp in list1:
                  length = len(list1)
                  break
      return length
first = 0
list1 = []
for i in range(2,1001):
      length = func(i)
      if first < length:
            first = length
            list1.append(i)
      else:
            continue
print(list1[-1])
运行结果是983

jerryxjr1220 发表于 2017-1-7 09:24:26

# -*- coding: utf-8 -*-
"""
Created on Sat Jan7 08:58:29 2017

@author: Jerry Xu
"""
import time
start = time.time()
def getprimes(n=1000):
    primes = *n
    primes,primes=False,False
    for i,prime in enumerate(primes):
      if prime:
            for j in range(i*i,n,i):
                primes=False
    primes,primes=False,False
    return
def loop(n):
    tmp = []
    m = 10
    while m%n not in tmp:
      tmp.append(m%n)
      m *= 10
    if not tmp[-1]:
      return 0
    else:
      return len(tmp)

longest, x = 0, 0
for i in getprimes():
    if loop(i)>longest:
      longest = loop(i)
      x = i
print (x, longest)
print ('Time used: %.3f sec' % (time.time()-start))
输出:
983 982
Time used: 0.429 sec

渡风 发表于 2017-1-23 09:51:48

此代码使用matlab编程
Problem26所用时间为0.63431秒
Problem26的答案为983
%% Problem26
% 题目26:找出1000以内的数字d,使得1/d拥有最大的循环圈        
function Output=Problem26(Input)
tic
if nargin==0
Input=1000;
end
Circle_Max=0;%储存最大的循环圈
Circle=0;%当前数的循环圈
R=1;
r=1;
Flag=0;
for ii=1:Input
    R=1;
    r=1;
    while (Flag==0)
      r=mod(r*10,ii);
      if r==0
            Circle=0;%1、r=0表示能除尽,没有循环圈;
            break
      else
            inx=find(r==R);
            if isempty(inx)==0
                %2、看r是否出现在R中,如果出现,表示已完成了循环圈,计算循环圈长度即可;
                Circle=length(R)-length(inx)+1;
                break
            else
                %3、如果r未出现在R中,则把r添加到R,然后继续循环.
                Temp=;
                R=Temp;               
            end
      end
    end
    if Circle>=Circle_Max
      Circle_Max=Circle;
      d=ii;
    end
end
Output=d;
toc
disp('此代码使用matlab编程')
disp(['Problem26所用时间为',num2str(toc),'秒'])
disp(['Problem26的答案为',num2str(Output)])

99592938 发表于 2017-3-15 17:03:35

def Recip(x):
    a=1
    l=[]
    while 1:
      if a<x:
            l.append(a)
            a=10*a
      elif a%x:
            a=a%x
      else:
            return 0
      if a in l:
            return(len(l)-l.index(a))

l_recip=
for d in range(1,1000):
    l_recip.append(Recip(d))
print('数字='+str(l_recip.index(max(l_recip))),'循环圈='+str(max(l_recip)))

>>>
数字=983 循环圈=982

99592938 发表于 2017-3-15 17:38:23

jerryxjr1220 发表于 2017-1-7 09:24
输出:
983 982
Time used: 0.429 sec

你的27行改为:
      return len(tmp)-tmp.index(m%n)
应该才更准确。
下面是我借鉴了你的循环圈算法,写的:
def Recip(x):
    a=1
    l=[]
    while a%x not in l:
      l.append(a%x)
      a*=10
    if not l[-1]:
      return 0
    else:
      return(len(l)-l.index(a%x))

l_recip=
for d in range(1,1000):
    l_recip.append(Recip(d))
print('数字='+str(l_recip.index(max(l_recip))),'循环圈='+str(max(l_recip)))

cwhsmile 发表于 2019-4-28 00:00:14

99592938 发表于 2017-3-15 17:03
>>>
数字=983 循环圈=982

果然是大神,用了相除统计余数,只要余数有相等的情况就会出现循环。

我是真笨,根本就想不到。。。。。。

永恒的蓝色梦想 发表于 2020-12-8 22:41:00

本帖最后由 永恒的蓝色梦想 于 2021-1-31 11:52 编辑

#include<iostream>
#include<cstring>



int main() {
    using namespace std;
    ios::sync_with_stdio(false);

    constexpr unsigned short UPPER_BOUND = 1000;
    static unsigned short n, max_n, length, max_length, a, appeared;


    for (n = 1; n < UPPER_BOUND; n++) {
      a = 1;

      for (length = 1;; length++) {
            a *= 10;
            a %= n;

            if (a) {
                if (appeared) {
                  length -= appeared;

                  if (length > max_length) {
                        max_n = n;
                        max_length = length;
                  }

                  break;
                }

                appeared = length;
            }
            else {
                break;
            }
      }

      memset(appeared, 0, n * sizeof(unsigned short));
    }


    cout << max_n << endl;
    return 0;
}

a1351468657 发表于 2021-3-12 17:06:31

#include <stdio.h>

int check_num(int n) //标记法
{
        int i, a = { 0 }, count = 0;
        i = 10 % n;
        if (i)
        {
                while (1)
                {
                        if (a)
                        {
                                return count;
                        }
                        a = 1;
                        i *= 10;
                        i %= n;
                        count++;
                }
        }
        else
        {
                return 0;
        }
}
main()
{
        int i, count, max = 0, num;
        for (i = 2; i < 1000; i++)
        {
                count = check_num(i);
                if (max < count)
                {
                        max = count;
                        num = i;
                }

        }
        printf("%d%d", num, max);
}

数字是983, 圈数是982

ft215378 发表于 2021-10-17 12:11:06

#找出小于 1000 的数字 d,1/d 的十进制表示含有最长的循环圈
#求1/n的循环圈长度
def loop(n):
    result = []
    res = 1
    while True:
      if n <= 10:
            res = (res*10) % n
            if res not in result:
                result.append(res)
            else:
                break
            
      elif 10 < n <= 100:
            res = (res*100) % n
            if res not in result:
                result.append(res)
            else:
                break
      elif 100 <= n <= 1000:
            res = (res*1000) % n
            if res not in result:
                result.append(res)
            else:
                break
               
    return len(result)
d = []
for i in range(1, 1001):
    d.append(loop(i))

print((d.index(max(d))+ 1), max(d))

guosl 发表于 2022-1-2 21:56:10

/*
答案:983
耗时:0.0230429秒(单核)
      0.00499988秒(八核)
*/
#include <iostream>
#include <algorithm>
#include <vector>
#include <omp.h>
using namespace std;

int getCycleLen(int n)//求出数n的循环节长度
{
vector<int> vC;
int r = 1;
vector<int>::iterator itr;
while (r > 0)
{
    r = r % n;
    itr = find(vC.begin(), vC.end(), r);
    if (itr != vC.end())
      break;
    vC.push_back(r);
    r *= 10;
}
if (r == 0)
    return 0;
int k = int(vC.end() - itr);
return k;
}

int main(void)
{
volatile int nMaxLen = 0, nVal = 0;
#pragma omp parallel for shared(nMaxLen,nVal) schedule(dynamic)
for (int i = 1; i < 1000; ++i)
{
    int k = getCycleLen(i);
    if (k > nMaxLen)
    {
#pragma omp critical
      {
      nMaxLen = k;
      nVal = i;
      }
    }
}
cout << nVal << endl;
return 0;
}

mathtimes 发表于 2022-2-23 12:48:38

import math
prime =
def isprime(n):
        if n<=prime[-1]:
                return n in prime
        else:
                i = prime[-1]+2
                while n>prime[-1]:
                        j = 0
                        while j<math.sqrt(len(prime)):
                                s = True
                                if i%prime==0:
                                        s = False
                                        break
                                j = j+1
                        if s:
                                prime.append(i)
                        i = i+1
                return n in prime
def odd(up,down):
        bits=[]
        sign=[]
        up %= down;
        up *= 10;
        bits.append(up//down)
        up %= down
        while up not in sign:
                sign.append(up)
                up *= 10;
                bits.append(up//down)
                up %= down
        bits.pop()
        return bits
maxv = 0
maxi = 0
for i in range(2,1000):
        if isprime(i):
                if len(odd(1,i))>maxv:
                        maxv = len(odd(1,i))
                        maxi = i
print(maxi,maxv)
页: [1]
查看完整版本: 题目26:找出小于1000的数字中令1/d拥有最长循环圈的数字d