试题 算法提高 欧拉函数

2020蓝桥杯习题汇总
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
  老师出了一道难题,小酱不会做,请你编个程序帮帮他,奖金一瓶酱油:
  从1—n中有多少个数与n互质?
  |||||╭══╮ ┌═════┐
  ╭╯让路║═║酱油专用车║
  ╰⊙═⊙╯ └══⊙═⊙═(坑爹的题面格式化,害得我用‘|’来代替空格,复制到记事本上看就变成正版的了)
输入格式
  输入共一行,表示一个整数n。
输出格式
  输出共一行,表示从1—n中与n互质的数的个数。
样例输入
30
样例输出
8
数据规模和约定
  60%的数据≤10^6
  100%的数据≤2*10^9

分析:
phi§等于p乘以每个1减去p的质因数(不重复)的倒数之差。
例如:30的质因数为2 3 5,则phi(30)=30*(1-1/2)(1-1/3)(1-1/5)=8
25的质因数为5 5,但是这里是不能重复的,所以phi(25)=25*(1-1/5)=20
这里借用了我之前写的分解质因数的一篇文章传送门
这道题问题在于怎样避免超时,所以我们应该尽量优化我们的代码

1.如果输入的数已经是质数了,那么可以直接输出,节省运行时间。
2.如果不是质数,那么就从2开始求解质因数;假设这个数能被2整除,那我们应该直接利用循环一直除,直到该数不能被2整除,然后进行下一个数,直到循环结束。例如n=80,首先从2开始判断是否为80的质因数,很明显80能被2整除,那我们就一直除,直到不能被2整除,即80/2=40,40/2=20,20/2=10,10/2=5,此时n=5不能被2整除,而且3和4也不行,直接到5/5=1,此时循环结束。
3.还有一个问题就是除尽某个质因数之后,要判断该数是否为质数,如果该数是质数,那么直接返回该数,这样子可以省下很多时间,避免超时。
4.其次,在判断质数时,分为偶数和奇数,偶数情况下都不是质数,奇数情况下只需要判断到根号n+1的情况即可,并且步长为2,这样也减少了时间上的消耗。

代码已通过蓝桥杯的测试,别忘了点个赞呀~

while True:
    try:
        n = int(input())
        result = n
        res = []
        def fun(n):
            # 判断质数
            if n < 2:
                return False
            elif n % 2 == 0:
                return False   
            for i in range(3,int(pow(n,0.5))+1,2):
                if n % i == 0:
                    return False
            return True
            
        for i in range(2,n+1):
            if n % i == 0:
                while n % i == 0:
                    n //= i
                res.append(i)
            if fun(n):
                res.append(n)
                break

        for i in set(res):
            result = result * (1-1/i)
        print(int(result))
    except:
        break

猜你喜欢

转载自blog.csdn.net/Python_Matlab/article/details/107614709
今日推荐