鱼C论坛

 找回密码
 立即注册
楼主: 欧拉计划

题目5:找出最小的能被1-20中每个数整除的数

[复制链接]
发表于 2016-10-6 00:04:02 | 显示全部楼层
  1. def euler(x):
  2.     result = x
  3.     while True:
  4.         for i in range(1,x+1):
  5.             if result%i:
  6.                 break
  7.         else:
  8.             return result
  9.         result += x

  10. if __name__ == '__main__':
  11.     print(euler(20))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-6 21:07:04 | 显示全部楼层
s = 11* 13 * 17 * 19*2520
i = s
x = 1
while x:
    if i%s == 0:
        if i%16 == 0:
            print(i)
            x = 0
    i = i * 2

不到一秒得到答案···不过要进行相当的分析,其实分析到这个地步基本上就不需要计算机了···
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-10 14:44:56 | 显示全部楼层
  1. 232792560
  2. [Finished in 0.1s]

  3. def gcd(x,y):
  4.         maxi = 1
  5.         for i in range(2,min(x,y)+1):
  6.                 if x%i ==0 and y%i ==0 and maxi <i:
  7.                         maxi = i
  8.         return maxi

  9. def lcm(a,b):
  10.     return a*b//gcd(a,b)
  11.    
  12. n = 3
  13. m = 2
  14. while n<=20:
  15.     m = lcm(m,n)
  16.     n+=1
  17. print(m)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-3 00:29:05 | 显示全部楼层
哎,写这个程序费了好久。
这个题目其实就是求1-20所有数的最小公倍数,将其转化为逐个求两项的最小公倍数问题。

  1. # Python 3.5实现求解最小的能被1-20中每个数整除的正整数

  2. def gcd(Num1,Num2):
  3.     '''辗转相除法即欧几里德算法(Euclidean algorithm)
  4.        用于求两个正整数之最大公因子的算法
  5.     '''
  6.     if Num1 < Num2:
  7.         Num1, Num2 = Num2, Num1

  8.     if Num1 == Num2:
  9.         return Num2
  10.     else:
  11.         while True:
  12.             r = Num1 % Num2
  13.             if r == 0:
  14.                 return Num2
  15.             else:
  16.                 Num1, Num2 = Num2, r


  17. def lcm(Num1, Num2):
  18.     '''求两个正整数之最小公倍数的算法'''
  19.     result = Num1 * Num2 // gcd(Num1, Num2)
  20.     return result


  21. def smallestMultiple(start, end):
  22.     Product = 1

  23.     if end < start:
  24.         start, end = end, start
  25.     if (not isinstance(start, int)) or (not isinstance(end, int)):
  26.           print('请输入两个正整数!')
  27.     else:
  28.         p = list(range(start, end + 1))        
  29.         lenP = len(p)

  30.         for i in range(lenP):
  31.             n1 = Product
  32.             n2 = p[i]
  33.             Product = lcm(n1, n2)
  34.                              
  35.     return Product


  36. sM = smallestMultiple(1, 10)
  37. print('最小的能被1-10中每个数整除的正整数为:%d'%sM)
  38. sM = smallestMultiple(1, 20)
  39. print('最小的能被1-20中每个数整除的正整数为:%d'%sM)
复制代码


>>>
最小的能被1-10中每个数整除的正整数为:2520
最小的能被1-20中每个数整除的正整数为:232792560
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2016-11-7 22:26:18 | 显示全部楼层
  1. #找出能被1到20之间各个数整除的正整数
  2. import math
  3. import time

  4. start=time.clock()
  5. def isPrime(n):
  6.     if n<2:
  7.         return False
  8.     elif n==2:
  9.         return True
  10.     else:
  11.         s=int(math.sqrt(n))
  12.         for i in range(2,s+1):
  13.             if n%i==0:
  14.                 return False
  15.         return True

  16. def findMax(n):
  17.     #找出1~n之间的各个质数,并求其乘积
  18.     s=1
  19.     for i in range(2,n+1):
  20.         if isPrime(i):
  21.             s=s*i
  22.     lista=list(range(2,n+1))
  23.     m=s
  24.     #最终结果必定为前面质因数乘积的倍数
  25.     #遍历列表,遇见不能整除的则加一次质数乘积
  26.     #再重新遍历,直到都可以整除
  27.     while True:
  28.         a=1
  29.         for x in lista:
  30.             if m%x!=0: #不能整除,须加一次再进入到下次循环重新遍历
  31.                 a=0
  32.                 break
  33.         if a==1:
  34.             break
  35.         m=m+s
  36.     return m

  37. print(findMax(20))
  38. end=time.clock()
  39. print("共耗时:"+str(end-start)+"秒!")
  40.    
  41.             

复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-9 11:06:19 | 显示全部楼层
  1. public class SmallestMultiple
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 //能被11-20整除的数就必然能被1-10整除,且必须是偶数
  6.                
  7.                 int num = 0;
  8.                 int flag = 0;
  9.                 while(flag != 10)
  10.                 {       
  11.                         flag = 0;
  12.                         num = num + 2;
  13.                         for(int i = 11;i <= 20;i++)
  14.                         {
  15.                                 if(num % i == 0)
  16.                                         flag = flag + 1;
  17.                                 else
  18.                                         break;
  19.                         }       
  20.                 }
  21.                 System.out.println("能被1-20整除的最小整数为:" + num);
  22.         }
  23. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-18 00:39:17 | 显示全部楼层
折腾了好久,失败了几次,越写越复杂,再看看其他人的代码后,怎么可以这么简洁!!!还有欧几里德算法……
  1. import math
  2. import time
  3. t = time.clock()

  4. def isprime(n):
  5.     if (n%2==0 and n!=2) or n==1: return False
  6.     for x in range(3,int(math.sqrt(n))+1,2):
  7.         if n%x==0 or n%5==0: return False
  8.     else: return True

  9. def euler05_2(count=10):
  10.     """2520是最小能被1-10中每个数字整除的正整数,最小的能被1-20中每个数整除地正整数是多少"""
  11.     from functools import reduce
  12.     def findprimefactors(n): #得到一个数的质因数列表,如果 n 为质数则直接返回 [n]
  13.         if n==1:return [1]
  14.         if n<1:return []
  15.         primelist = [i for i in range(2,n+1) if isprime(i)]
  16.         iteritem = iter(primelist)
  17.         item = next(iteritem)
  18.         primefactors = []
  19.         while True:
  20.             if isprime(n) or n<3:
  21.                 primefactors.append(int(n))
  22.                 return primefactors
  23.             elif n%item == 0:
  24.                 primefactors.append(item)
  25.                 n /= item
  26.                 continue
  27.             try:
  28.                 item = next(iteritem)
  29.             except:
  30.                 return primefactors
  31.     def lcm(a,b): #得到任意两个正整数最小公倍数的质因数列表
  32.         if type(a) is int:
  33.             la = findprimefactors(a)
  34.         elif type(a) is list:
  35.             la = a
  36.         lb = findprimefactors(b)
  37.         temp = []
  38.         for i in la[:]:
  39.             if i in lb: temp.append(i); la.remove(i); lb.remove(i)
  40.             else: temp.append(i); la.remove(i)
  41.         if lb: temp.extend(lb)
  42.         return temp

  43.     # 得到从 1-count 的最小公倍数的质因数列表:
  44.     allcm = []
  45.     start = True
  46.     for n in range(1,count):
  47.         if start:
  48.             allcm = lcm(n,n+1)
  49.             start = False
  50.         else:
  51.             allcm.extend(lcm(allcm,n+1))

  52.     # 把allcm的所有元素相乘:
  53.     result = 1
  54.     for n in allcm:
  55.         result *= n   
  56.     return result

  57. t = time.clock()
  58. print('answer:',euler05_2(20),'\n--time:',time.clock()-t)
复制代码


写得实在是太长了点
answer:232792560
time: 0.0012959836349992165
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-7 00:48:28 | 显示全部楼层
  1. # encoding:utf-8
  2. from time import time
  3. import math
  4. '''

  5. 2520 是最小的能被 1-10 中每个数字整除的正整数。
  6. 最小的能被 1-20 中每个数整除的正整数是多少?
  7. '''
  8. # 拆分素数因子
  9. def findPrimeFactors(n, l_pr):
  10.     if isPrime(n):
  11.         return [n]
  12.     sqr_n = int(math.sqrt(n)) + 1
  13.     result = list()
  14.     for pr in l_pr:
  15.         if n % pr == 0:
  16.             result.append(pr)
  17.             result.extend(findPrimeFactors(int(n / pr),l_pr))
  18.             break
  19.         if pr > sqr_n:
  20.             break
  21.     return result

  22. # 是否为素数
  23. def isPrime(n):
  24.     if not isinstance(n, int):
  25.         print('输入有误!')
  26.         return
  27.     if n < 4:
  28.         return True;
  29.     if n % 2 == 0 or n % 3 == 0:
  30.         return False

  31.     for i in range(3, int(math.sqrt(n)) + 1, 2):
  32.         if not n % i:
  33.             return False
  34.         
  35.     return True
  36. # 查找到2~N的素数   
  37. def findPrimesToN(number):
  38.     if number == 1:
  39.         return [2]
  40.     elif number == 2:
  41.         return [2, 3]
  42.     else:
  43.         l_pn = [2, 3]
  44.         n = 3
  45.         while max(l_pn) < number:
  46.             n += 2
  47.             ispm = True
  48.             sqr_n = int(math.sqrt(n))
  49.             for t in l_pn:
  50.                 if n % t == 0:
  51.                     ispm = False
  52.                     break
  53.                 if t > sqr_n:
  54.                     break
  55.             if ispm:
  56.                 l_pn.append(n)
  57.                
  58.         return l_pn


  59. number = int(input('输入数值:'))
  60. start = time()
  61. result = 1
  62. fac_dict = dict()
  63. l_pr = findPrimesToN(int(math.sqrt(number))+1)
  64. print(findPrimeFactors(25,l_pr))
  65. for n in range(1, number+1):
  66.     fac_list = findPrimeFactors(n, l_pr)
  67.     fac_set = set(fac_list)
  68.     for each in fac_set:
  69.         num = fac_list.count(each)
  70.         if not fac_dict.get(each) or fac_dict.get(each) < num:
  71.             fac_dict[each] = num
  72.     #print(fac_dict)
  73. for key in fac_dict.keys():
  74.     result *= (key ** fac_dict.get(key))
  75. print('能被1~~%d整除的最小整数是%d' % (number, result))
  76. print('cost %.3f sec' % (time() - start))  
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-12 22:13:45 | 显示全部楼层
本帖最后由 渡风 于 2017-1-12 22:15 编辑

此代码使用matlab编程
Problem5所用时间为0.0016794秒
Problem5的答案为232792560
  1. %题目5:找出最小的能被1-20中每个数整除的数
  2. function Output=Problem5(Input)
  3. tic
  4. if nargin==0
  5.     Input=20;
  6. end
  7. [Rank1,Rank2]=Com_Prime_Rank(Input);%Rank1是素数列,Rank2是合数列
  8. L1=length(Rank1);
  9. L2=length(Rank2);
  10. for ii=1:L2
  11.     for jj=1:L1
  12.         if mod(Rank2(ii),Rank1(jj))==0
  13.             Rank2(ii)=Rank2(ii)/Rank1(jj);
  14.         end
  15.     end
  16. end
  17. for kk=1:L2-1
  18.     temp=kk;
  19.     for ll=temp+1:L2
  20.         if mod(Rank2(ll),Rank2(temp))==0
  21.             Rank2(ll)=Rank2(ll)/Rank2(temp);
  22.         end
  23.     end
  24. end
  25. Output=prod(Rank1)*prod(Rank2);
  26. toc
  27. disp('此代码使用matlab编程')
  28. disp(['Problem5所用时间为',num2str(toc),'秒'])
  29. disp(['Problem5的答案为',num2str(Output)])
  30. end
  31. %% 子程序
  32. %输入一个数使其生成小于它素数列和合数列(包括自身)
  33. function [Output1,Output2]=Com_Prime_Rank(Input)
  34. if nargin==0
  35.     Input=20;
  36. end
  37. Rank1=2;
  38. Rank2=0;
  39. for ii=3:Input
  40.      temp=ii;
  41.      Judge=1;
  42.      for jj=floor(sqrt(temp))+1:-1:2
  43.          if mod(temp,jj)==0
  44.              Judge=0;
  45.              break
  46.          end
  47.      end
  48.      if Judge==1
  49.         Rank_Temp1=[Rank1,temp];
  50.         Rank1=Rank_Temp1;
  51.      else
  52.         Rank_Temp2=[Rank2,temp];
  53.         Rank2=Rank_Temp2;
  54.      end
  55. end
  56. Output1=Rank1;
  57. Output2=Rank2(2:end);
  58. disp(Output2)
  59. end
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-2-2 13:51:20 | 显示全部楼层
  1. '''
  2. 思路:
  3. 1、找出1-20中,每个数的质因数,并存放在列表中,如果列表中的数已经包含该数的质因数,则不再向列表中添加

  4. 2、从20开始每个数验证一次,想想就感觉非常耗时,还是不去实现了
  5. '''

  6. import time

  7. def is_prime(number):
  8.     '判断是否为质数'
  9.     flag = True
  10.     for i in range(2, number):
  11.         if number % i == 0:
  12.             flag = False
  13.     return flag

  14. def multiple_1(number):
  15.     '思路1完成题目'
  16.     multiple = 1
  17.     list_prime = [1]
  18.     list_temp = [1]
  19.     for i in range(1, number + 1):
  20.         temp = i
  21.         j = 2
  22.         while j <= temp:
  23.             if temp % j == 0 and is_prime(j):
  24.                 list_temp.append(j)
  25.                 temp /= j
  26.                 j = 1
  27.             j += 1
  28.         for n in list_temp:
  29.             if list_temp.count(n) > list_prime.count(n):
  30.                 for m in range(0, list_temp.count(n) - list_prime.count(n)):
  31.                     list_prime.append(n)
  32.         list_temp.clear()
  33.         list_temp.append(1)
  34.     for i in list_prime:
  35.         multiple *= i
  36.     return multiple

  37. start = time.clock()
  38. print(multiple_1(20))
  39. end = time.clock()
  40. print('程序按思路1执行了%fs。' %(end - start))
复制代码

执行结果:
232792560
程序执行了0.000230s。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-6 14:19:44 | 显示全部楼层
  1. i=20
  2. while True:
  3.     for j in range(1,21):
  4.         if i%j==0:
  5.             continue
  6.         else:
  7.             break
  8.     else:
  9.         print(i)
  10.         break
  11.     i+=1
  12.         
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 0 反对 1

使用道具 举报

发表于 2017-3-14 15:32:17 | 显示全部楼层
先把所有质数挑出来2*3*5*7*11*13*17*19,然后循环检测
  1. num=n=2*3*5*7*11*13*17*19
  2. f=k=1
  3. while k:
  4.     for i in range(1,21):
  5.         if num%i:
  6.             f=0
  7.             break
  8.     if f:
  9.         print(num)
  10.         k=0
  11.     f=1
  12.     num+=n
复制代码

当然笔算也能算出结果,把剩下的合数分解因素,若能以已有质数积求得,就忽略,若不能,则再添质数,得到答案2*3*5*7*11*13*17*19*2*2*2*3=232792560
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-14 15:35:30 | 显示全部楼层
镜中人31 发表于 2016-10-6 21:07
不到一秒得到答案···不过要进行相当的分析,其实分析到这个地步基本上就不需要计算机了···

对,你再乘2就行了。
笔算也能算出结果,把质数都列出来,剩下的合数分解因素,若能以已有质数积求得,就忽略,若不能,则再添质数,最后全相乘,得到答案2*3*5*7*11*13*17*19*2*2*3*2=232792560
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-27 10:42:35 | 显示全部楼层
  1. #include <stdio.h>

  2. int main(void)
  3. {
  4.     int multiple = 0;
  5.     int i;
  6.     _Bool flag = 0;

  7.     while(!flag)
  8.     {
  9.         multiple += 3 * 5 * 7 * 11 * 13 * 17 * 19;

  10.         for(i = 2; i < 21; i++)
  11.         {
  12.             if(multiple % i)
  13.             {
  14.                 break;
  15.             }
  16.         }

  17.         if(i > 20)
  18.         {
  19.             break;
  20.         }
  21.     }

  22.     printf("%d\n", multiple);

  23.     return 0;
  24. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-27 10:49:40 | 显示全部楼层
  1. def main():
  2.     result = 0

  3.     while True:
  4.         result += 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19
  5.         for each in range(1, 21):
  6.             if result % each:
  7.                 break

  8.         if each == 20:
  9.             break

  10.     print(result)

  11. if __name__ == "__main__":
  12.     main()
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-16 21:29:22 | 显示全部楼层
#求能被1-20中每个数整除的最小正整数
#设a,b的最大公约数为(a,b),最大公倍数为[a,b]
#则有 a*b = (a,b)*[a,b]

  1. import time


  2. start = time.time()
  3. def gcd(x,y):
  4.     x,y = max(x,y),min(x,y)
  5.     r = x%y
  6.     if r == 0:
  7.         return y
  8.     else:
  9.         return gcd(y,r)


  10. n1 = 2*3//gcd(2,3)

  11. for n2 in range(4,21):
  12.     n1 = n1*n2//gcd(n1,n2)

  13. print(n1)

  14. end = time.time()

  15. print(end-start)
复制代码


结果:232792560
时间:0.0070035457611083984s
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-30 21:34:56 | 显示全部楼层
  1. #include<stdio.h>

  2. int main()
  3. {
  4.         const int L = 20;
  5.         int num = 1;
  6.         int * arr = malloc(L * sizeof(int));
  7.         for (int i = 0;i < L;i++)
  8.         {
  9.                 arr[i] = i + 1;
  10.                 for (int j = 0;j < i;j++)
  11.                 {
  12.                         if (arr[i] % arr[j] == 0)
  13.                         {
  14.                                 arr[i] /= arr[j];
  15.                         }
  16.                 }
  17.                 num *= arr[i];
  18.         }
  19.         printf("%d\n", num);
  20.         free(arr);
  21.         return 0;
  22. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-4 16:39:09 | 显示全部楼层
答案是232792560

  1. #include<stdio.h>
  2. //20以内涉嫌重复的只有2,3,5,7,将其除掉即可
  3. //2最多有5次:16,3最多有2次:9
  4. int main(void)
  5. {
  6.         int i,num,rst=1;
  7.        
  8.         for(i=2;i<=20;++i)
  9.         {
  10.                 num = i;
  11.                 if(num%2==0)
  12.                         while(num%2==0)        num /= 2;
  13.                 if(num%3==0)
  14.                         while(num%3==0)        num /= 3;
  15.                 if(num%5==0)
  16.                         num /= 5;
  17.                 if(num%7==0)
  18.                         num /= 7;
  19.                 rst = rst * num;
  20.         }
  21.        
  22.         rst = rst * 16 * 9 * 5 * 7;
  23.         //乘2^4=16,3^2=9,5,7
  24.         printf("%d\n",rst);
  25.         return 0;
  26. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-6 22:23:28 | 显示全部楼层
  1. #include<stdio.h>
  2. int main()
  3. {
  4.         int x[21]={0};
  5.         int a,b;
  6.        
  7.         for(a=20;x[20]==0;a++)
  8.         {
  9.        
  10.                 for(b=1;b<21;b++)
  11.                 {
  12.                         if(a%b==0)
  13.                         {
  14.                                
  15.                                 x[b]=a;
  16.                         }
  17.                         else
  18.                         {
  19.                                
  20.                                 break;
  21.                         }       
  22.                        
  23.                 }
  24.        
  25.         }
  26.        
  27.         printf("%d ",x[20]);

  28.         return 0;
  29. }
复制代码


求告知这种算法怎么修改能更快速和简单
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-7 15:38:48 | 显示全部楼层
  1. public static void main(String[] args) {
  2. //                5、2520是最小能被1-10每个数字整除的正整数。最小的能被1-20中每个数整除的正整数是多少?
  3.                 int i=20;
  4.                 while(!cmp(i)){
  5.                         i++;
  6.                 }
  7.                 System.out.println(i);
  8.         }
  9.         public static boolean cmp(int num) {
  10.                 for(int i=2;i<21;i++){
  11.                         if(num%i!=0){
  12.                                 return false;
  13.                         }
  14.                 }
  15.                 return true;
  16.         }
复制代码
感觉速度有点慢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-20 04:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表