Consider the fraction, n/d, where n and d are positive integers. If nd and HCF(n,d)=1, it is called a reduced proper fraction.

If we list the set of reduced proper fractions for d  8 in ascending order of size, we get:

1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8

It can be seen that there are 21 elements in this set.

How many elements would be contained in the set of reduced proper fractions for d  1,000,000?

题目大意:

考虑分数 n/d, 其中n 和 d 是正整数。如果 nd 并且最大公约数 HCF(n,d)=1, 它被称作一个最简真分数。

如果我们将d  8的最简真分数按照大小的升序列出来,我们得到:

1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5 , 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8

可知该集合中共有21个元素。
 1,000,000的最简真分数集合中包含多少个元素?

算法一(超时):

优化技巧:

1、当分母n是素数,则以n为分母的最简真分数的数目为n-1

2、当分母和分子奇偶不同的时候,进一步检查分母和分子的最大公约数

#include<stdio.h>
#include<stdbool.h>
void swap(int* a, int* b) //交换两值的函数
{
int t;
t = *a;
*a = *b;
*b = t;
} int gcd(int a, int b) //求最大公约数函数
{
int r;
if(a < b) swap(&a, &b);
while(b) {
r = a % b;
a = b;
b = r;
}
return a;
} bool prim(int n) //判断素数函数
{
int i;
for(i = ; i * i <= n; i++) {
if(n % i == ) return false;
}
return true;
} bool fun(int a, int b) //判断两整数奇偶是否相同
{
return !((a & ) & (b & ));
} void solve()
{
int i, j, t;
long long count = ;
for(i = ; i <= ; i++) {
if(i % && prim(i)) {
count += i - ;
continue;
}
count++;
for(j = ; j < i; j++) {
if(fun(i,j) && (i % j != )) {
t = gcd(i, j);
if(t == ) count++; //如果i,j互素,符合
}
}
}
printf("%lld\n", count);
} int main()
{
solve();
return ;
}

算法二:

将1~1000000的整数分奇偶两部分计算,依然超时

#include<stdio.h>
#include<stdbool.h> #define N 1000000 int gcd(int a, int b) //求最大公约数函数
{
int r;
while(b) {
r = a % b;
a = b;
b = r;
}
return a;
} bool prim(int n) //判断素数函数
{
int i;
for(i = ; i * i <= n; i++) {
if(n % i == ) return false;
}
return true;
} bool fun(int a, int b) //判断两整数奇偶是否相同
{
return !((a & ) & (b & ));
} void solve()
{
int i, j, t;
long long count = ;
for(i = ; i <= N; i += ) {
count++;
for(j = ; j < i; j += ) {
t = gcd(i, j);
if(t == ) count++;
} }
for(i = ; i < N; i += ) {
count++;
if(prim(i)) {
count += i - ;
continue;
} else {
for(j = ; j < i; j++) {
if(gcd(i, j)) count++;
}
} }
printf("%lld\n", count);
} int main()
{
solve();
return ;
}

算法三:

#include<stdio.h>
#include<stdbool.h>
#include<math.h> #define N 1000001 bool a[N]; void Eratosthenes()
{
int i, M, j;
for(i = ; i < N; i++) {
a[i] = true;
}
M = (int)sqrt(N);
for(i = ; i <= M; i++) {
if(a[i]) {
j = i * i;
for(; j < N; j += i)
a[j] = false;
}
}
} int fun(int n)
{
int t, i, count, j;
t = n / ;
i = ;
count = n - ;
while(i <= t) {
if(a[i]) {
if(n % i == ) {
count--;
for(j = i; j * i < n; j++) {
count--;
}
}
}
i++;
}
return count;
} int main()
{
int i;
long long count = ; Eratosthenes(); for(i = ; i < N; i++) {
if(a[i]) {
count += i - ;
} else {
count += fun(i);
}
}
printf("%lld\n", count); return ;
}

算法四:使用欧拉函数

//(Problem 72)Counting fractions
// Completed on Tue, 18 Feb 2014, 14:08
// Language: C11
//
// 版权所有(C)acutus (mail: acutus@126.com)
// 博客地址:http://www.cnblogs.com/acutus/ #include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h> #define N 1000001 int phi[N]; //数组中储存每个数的欧拉数 void genPhi(int n)//求出比n小的每一个数的欧拉数(n-1的)
{
int i, j, pNum = ;
memset(phi, , sizeof(phi)) ;
phi[] = ;
for(i = ; i < n; i++)
{
if(!phi[i])
{
for(j = i; j < n; j += i)
{
if(!phi[j])
phi[j] = j;
phi[j] = phi[j] / i * (i - );
}
}
}
} void solve()
{
int i;
long long ans =;
for(i = ; i < N; i++) {
ans += phi[i];
}
printf("%lld\n", ans);
} int main()
{
genPhi(N);
solve();
return ;
}
Answer:
303963552391

(Problem 72)Counting fractions的更多相关文章

  1. (Problem 73)Counting fractions in a range

    Consider the fraction, n/d, where n and d are positive integers. If nd and HCF(n,d)=1, it is called ...

  2. (Problem 33)Digit canceling fractions

    The fraction 49/98 is a curious fraction, as an inexperienced mathematician in attempting to simplif ...

  3. (Problem 57)Square root convergents

    It is possible to show that the square root of two can be expressed as an infinite continued fractio ...

  4. (Problem 42)Coded triangle numbers

    The nth term of the sequence of triangle numbers is given by, tn = ½n(n+1); so the first ten triangl ...

  5. (Problem 41)Pandigital prime

    We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly o ...

  6. (Problem 70)Totient permutation

    Euler's Totient function, φ(n) [sometimes called the phi function], is used to determine the number ...

  7. (Problem 74)Digit factorial chains

    The number 145 is well known for the property that the sum of the factorial of its digits is equal t ...

  8. (Problem 46)Goldbach's other conjecture

    It was proposed by Christian Goldbach that every odd composite number can be written as the sum of a ...

  9. (Problem 53)Combinatoric selections

    There are exactly ten ways of selecting three from five, 12345: 123, 124, 125, 134, 135, 145, 234, 2 ...

随机推荐

  1. 漏掉的账目(用C语言去重)

    问题描述: 某财务部门结账时发现总金额不对头.很可能是从明细上漏掉了某1笔或几笔.如果已知明细账目清单,能通过编程找到漏掉的是哪1笔或几笔吗? 如果有多种可能,则输出所有可能的情况. 我们规定:用户输 ...

  2. HDOJ 1561 - 树形DP,泛化背包

    刚看题...觉得这不是棵树...可能有回路...仔细一想..这还真是棵树(森林)...这是由于每个城堡所需要提前击破的城堡至多一个..对于一个城堡.其所需提前击破的城堡作为其父亲构图.... dp[k ...

  3. JavaScript之JS实现动画效果

    在前面的随笔中介绍了如何用DOM技术修改文档的央样式信息,用JavaScript添加样式信息可以节约我们的时间和精力,但总的来说,CSS仍是完成这类任务的最佳工具.但是有一个应用领域是目前的CSS无能 ...

  4. ASP.NET MVC开发必看系列

    一.关于HTTP协议的那些事 这可以说我们开发WEB程序的空气,推荐不断温故知新! HTTP协议 (一) HTTP协议详解 HTTP协议 (二) 基本认证 HTTP协议 (三) 压缩 HTTP协议 ( ...

  5. VC++ SetLayeredWindowAttributes 部分窗口透明鼠标穿透

    在初始化中使用下面两行代码 ModifyStyleEx(0, WS_EX_LAYERED); ::SetLayeredWindowAttributes(m_hWnd, RGB(1, 255, 0), ...

  6. HDU 5584 LCM Walk(数学题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5584 题意:(x, y)经过一次操作可以变成(x+z, y)或(x, y+z)现在给你个点(ex, e ...

  7. Hibernate学习之关系映射(转)

    一.一对多 "一对多"是最普遍的映射关系,简单来讲就如消费者与订单的关系.一对多:从消费者角的度来说一个消费者可以有多个订单,即为一对多.多对一:从订单的角度来说多个订单可以对应一 ...

  8. 【转】说说JSON和JSONP,也许你会豁然开朗,含jQuery用例

    由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Socket通讯 ...

  9. [暂停一天]从零开始PHP学习 - 第六天

    今天这个系列没有时间去写了 在公司完善一个项目     已经备好6瓶咖啡 两天 + 一夜 完成这个项目  真是苦逼 诶 反正这几天 明白一个道理:别以为你多牛B 你不会的东西多了!  比你牛B的人也多 ...

  10. C#学习日志 day 2 plus ------ hyper-V 开启方法

    hyper-V的开启需要两个步骤. 第一是在bios中开启 virtualization technology--虚拟化技术 在process setting中改为enabled. 进入bios界面的 ...