POJ 2407 Relatives

题目大意:

        给定一个正整数n(1 ≤ n ≤ 1,000,000,000),求小于它并且和它互质的数的数量(即欧拉函数)。

        两数互质即两数的最大公约数只有1一个,即两者只能同时被1整除而不能被其它任何数同时整除。

        现有多个测例,每个测例中都会给出一个正整数n,对于每个测例都要输出其欧拉函数的值。

题目链接

注释代码:

//欧拉函数的计算公式为:
//eula(n) = n × ∏(1 - 1/pi)
//其中p为n的所有因子
//筛法就是将n的所有因子展开后一个个筛选
//其中因子从从小到大进行扫描筛选
//如果碰到一个因子(此时n必然能整除它)就筛选到
  //在结果上乘以一个(1 - 1/pi),并将该因子除尽
  //那剩余的数继续筛选其它因子
//比如n = 1260 = 2 × 2 × 3 × 5 × 7
//因子d从2开始扫描,发现1260可以整除2,将2筛选出,用ans × (1 - 1/2)
//ans初始化为n
//然后将所有2因子都除去,则还剩n = 105 = 3 × 5 × 7,然后用同样的方法得到因子3
//再在ans上乘以(1 - 1/3),知道最后将7也算进去为止
//为了减小扫描范围,每扫描出一个就将d的上限降低为√n,因为每筛选出一个p就要从n中除去因子p
  //由于n减小,d的上限也必然的减小,上限用d * d <= n很合适

//求欧拉函数表的模板:
// void
// eular() {//求1 - N的欧拉函数值,直接打表
// 
// 	int		i, j;
// 
// 	eu[1] = 0; //一般1的欧拉函数值由题意决定,这里默认为1
// 	for ( i = 2; i <= N; i++ )
// 		if ( !eu[i] )
// 			for ( j = i; j <= N; j += i ) {
// 
// 				if ( !eu[j] )
// 					eu[j] = j;
// 
// 				eu[j] -= eu[j] / i;
// 			}
// }

/*                             
 * Problem ID : POJ 2407 Relatives
 * Author     : Lirx.t.Una                             
 * Language   : C                
 * Run Time   : 0 ms                             
 * Run Memory : 172 KB                             
*/

#include <stdio.h>

int
main() {
	
	int		n;//给定的正整数
	int		d;//divisor,因子(被除数),用筛法扫描时的筛选因子
	int		ans;
	
	while ( scanf("%d", &n), n ) {
		
		if ( 1 == n ) {//1的欧拉函数必然为0
			
			puts("0");
			continue;
		}
		
		for ( ans = n, d = 2; d * d <= n; d++ )
			if ( !( n % d ) ) {//查看d是否是n的因子
				
				ans -= ans / d;//欧拉函数的公式
				
				do {
					
					n /= d;//将因子d从n中除去
				}
				while ( !( n % d ) );
			}
			
		//特殊情况,比如n已经为5 × 7了,刚除去5,d刚好涨到6而n由于除去5而变成7
		//此时6 * 6 > 7而退出上面的循环而漏掉了最后一个因子7
		//此语句就是为了避免这种漏网之鱼
		if ( n != 1 )
			ans -= ans / n;
			
		printf("%d\n", ans);
	}
	
	return 0;
}


无注释代码:

#include <stdio.h>

int
main() {

	int		n;
	int		d;
	int		ans;

	while ( scanf("%d", &n), n ) {

		if ( 1 == n ) {
		
			puts("0");
			continue;
		}
	
		for ( ans = n, d = 2; d * d <= n; d++ )
			if ( !( n % d ) ) {
			
				ans -= ans / d;

				do {
				
					n /= d;
				}
			   	while ( !( n % d ) );
			}

		if ( n != 1 )
			ans -= ans / n;

		printf("%d\n", ans);
	}

	return 0;
}

单词解释:

relative:adj, 相对的,相关的; n, 亲戚,相关物

prime:n, 素数(质数)

be prime to:和...互质

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值