当前位置: 首页 > news >正文

欧拉计划 Project Euler 71(有序分数)题解

欧拉计划 Project Euler 71 题解

  • 题干
    • 有序分数
  • 思路
    • 为什么可以这样 理论依据
  • code

题干

有序分数

考虑形如 n d \frac{n}{d} dn的分数,其中 n n n d d d均为正整数。如果 n < d n<d n<d且其最大公约数为1,则称该分数为最简真分数。
将所有 d ≤ 8 d\leq8 d8的最简真分数构成的集合按大小升序排列:
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 \frac 1 8, \frac 1 7, \frac 1 6, \frac 1 5, \frac 1 4, \frac 2 7, \frac 1 3, \frac 3 8, \mathbf{\frac 2 5}, \frac 3 7, \frac 1 2, \frac 4 7, \frac 3 5, \frac 5 8, \frac 2 3, \frac 5 7, \frac 3 4, \frac 4 5, \frac 5 6, \frac 6 7, \frac 7 8 81,71,61,51,41,72,31,83,52,73,21,74,53,85,32,75,43,54,65,76,87
可以看出 2 5 \frac{2}{5} 52 3 / 7 3/7 3/7直接左邻的分数。
将所有的 d ≤ 1000000 d\leq1000000 d1000000的最简真分数按大小升序排列,求此时 3 7 \frac{3}{7} 73直接左邻的分数的分子。

思路

很显然这是不能暴力构造的,因为数据太过庞大了。
我们可以枚举所有的 d ≤ 1000000 d\leq1000000 d1000000,对于每个 d d d,令 d = f l o o r ( 3 ∗ d − 1 ) / 7 d=floor(3 * d-1)/7 d=floor(3d1)/7,这样是为了确保 n d < 3 7 \frac{n}{d} < \frac{3}{7} dn<73,然后检查 n n n d d d是否互质,维护目前最大的 n d \frac{n}{d} dn即可

为什么可以这样 理论依据

对于每个分母 q q q,我们只需要考虑一个分子 p p p,即:
p = ⌊ a ⋅ q − 1 b ⌋ p=\lfloor\frac{a\cdot q-1}{b}\rfloor p=baq1
这是保证 p q < a b \frac{p}{q} < \frac{a}{b} qp<ba最大的那个 p q \frac{p}{q} qp
为了进一步加速,我们可以从大到小便利分母,并尽早结束循环
定义:
δ = a ⋅ q − b ⋅ p \delta = a\cdot q - b\cdot p δ=aqbp
若找到某个分数满足 δ = 1 \delta=1 δ=1那么这个分数已经是距离 a b \frac{a}{b} ba最近的最简真分数,可立即停止,这里有理论依据支撑的

code

// --->428570 999997
#include <bits/stdc++.h>using namespace std;using ll = long long;// 这段 lambda 内部的代码会在 main() 调用之前被执行。
int __OI_INIT__ = []() {ios::sync_with_stdio(0), cin.tie(0);cout.tie(0);cout << fixed << setprecision(12); // 设置输出浮点数默认精度为 12 位。return 0;
}();// 用法
/*int a = 1;double k = 2.0;string s = "hello world";_(a, k, s);输出 --->1 2.000000000000 hello world
*/
template<class... Args> void _(Args... args) {auto _ = [&](auto x) { cout << x << " "; };cout << "--->";int arr[] = {(_(args), 0)...};cout << "\n";
}void solve() {const int li = 1000000;int bn = 0, bd = 1;for (int d = 1; d <= li; ++d) {int n = (3 * d - 1) / 7;if (__gcd(n, d) == 1) {if (static_cast<long long>(n) * bd > static_cast<long long>(bn) * d) {bn = n;bd = d;}}}_(bn, bd);}int main() {int tt = 1;// cin >> tt;while (tt--) {solve();}}

相关文章:

  • OPC UA 协议介绍
  • Antd中Form详解:
  • volatile是什么
  • # YOLOv3:基于 PyTorch 的目标检测模型实现
  • RevIN(Reversible Instance Normalization)及其在时间序列中的应用
  • 软件测试服务公司分享:国产化适配测试的重要性和关键要素
  • paimon中批和流查看过去的快照的数据及变动的数据
  • OSCP备战-Kioptrix4详细教程
  • Python+1688 API 开发教程:实现商品实时数据采集的完整接入方案
  • Conda在powershell终端中无法使用conda activate命令
  • React百日学习计划-Grok3
  • 如何学习VBA_3.3.3 VBA程序写好后,如何进行调试,直到程序运行
  • 数据结构—(链表,栈,队列,树)
  • 重生之我是CSDN大佬
  • 在VirtualBox中安装虚拟机后不能全屏显示的问题及解决办法
  • 从零实现一个高并发内存池 - 1
  • [ctfshow web入门] web72
  • Linux精确列出非法 UTF-8 字符的路径或文件名
  • logback 日志归档,解决主日志和归档日志分别定义不同的周期
  • EXCEL Python 实现绘制柱状线型组合图和树状图(包含数据透视表)
  • 加拿大总理宣布新内阁名单
  • 中央结算公司:减免境外央行类机构账户开户费用
  • 美国三大指数全线高开:纳指涨逾4%,大型科技股、中概股大涨
  • 影子调查丨三名“淘金客”殒命雪峰山:千余废弃金矿洞的监管难题
  • 区域国别学视域下的东亚文化交涉
  • 2025年上海好护士揭晓,上海护士五年增近两成达12.31万人