蓝桥杯 欧拉函数 C++算法提高 HERODING的蓝桥杯之路

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

解题思路:
这道题目最关键的一点是使用欧拉函数!!!
如果你不用欧拉函数,而是通过for循环,从1到n分别判断是否互为质数(用辗转相除法可以解决),那么恭喜你,成功超时了!所以必须使用欧拉函数。
欧拉函数的思路很简单,就是枚举每一个数,如果是因子,则筛去所有该因子,并且减去有该因子的所有数。代码如下(包括了我失败的思路在内,不过注释掉了):

#include<bits/stdc++.h>

using namespace std;

long long lcm(int m, int n){//辗转相除法 
	if(m % n == 0){
		return n;
	}else{
		return lcm(n, m % n);
	}
}

int phi(int x){//注:ans即为phi(x)的值
    int ans = x;//先令phi(x)=x,公式中的前部分
    for (int i = 2; i * i <= x; i ++){//枚举每个数(注意,phi要求的因子是质数,而这里枚举的是所有数。至于为什么要这么枚举,请看代码下边的解释)
        if(x % i == 0){//如果这个数是因子
            ans -= ans / i;//套公式x*(1-1/pi)=x-x/pi即这里的ans-=ans/i;
            while(x % i == 0) x /= i;//筛去phi(x)中x的所有i因子
        }
    }
    if(x > 1)//筛后有剩余的数,说明这个数也是一个质因子
        ans -= ans/x;//同理套公式
    return ans;//答案
}

int main(){
	long long n;
	int count = 0;
	cin >> n;
//	for(int i = 1; i < n; i ++){
//		if(lcm(n, i) == 1){
//			count ++;
//		}
//	}
	count = phi(n);
	cout << count;
	return 0;
} 

感谢这位老哥的思路:https://blog.csdn.net/DT2131/article/details/52116264

猜你喜欢

转载自blog.csdn.net/HERODING23/article/details/106709073
今日推荐