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

《P1763 埃及分数》

题目描述

来源:BIO 1997 Round 1 Question 3

在古埃及,人们使用单位分数的和(形如 a1​ 的,a 是自然数)表示一切有理数。如:32​=21​+61​,但不允许 32​=31​+31​,因为加数中有相同的。对于一个分数 ba​,表示方法有很多种,但是哪种最好呢?首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越好。如:

4519​4519​4519​4519​4519​​=31​+121​+1801​=31​+151​+451​=31​+181​+301​=41​+61​+1801​=51​+61​+181​​

最好的是最后一种,因为 181​ 比 1801​,451​,301​ 都大。
注意,可能有多个最优解。如:

21159​21159​​=41​+361​+6331​+37981​=61​+91​+6331​+37981​​

由于方法一与方法二中,最小的分数相同,因此二者均是最优解。

给出 a,b,编程计算最好的表达方式。保证最优解满足:最小的分数 ≥1071​。

输入格式

一行两个整数,分别为 a 和 b 的值。

输出格式

输出若干个数,自小到大排列,依次是单位分数的分母。

输入输出样例

输入 #1复制

19 45

输出 #1复制

5 6 18

说明/提示

1<a<b<1000

代码实现:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

typedef long long LL;
vector<LL> ans_d, temp_d;
int max_depth;

// 求最大公约数
LL gcd(LL a, LL b) {
    return b == 0 ? a : gcd(b, a % b);
}

// 约分分数 a/b
pair<LL, LL> reduce(LL a, LL b) {
    LL g = gcd(a, b);
    return {a / g, b / g};
}

// 比较两个解的优劣
bool better(const vector<LL>& a, const vector<LL>& b) {
    if (a.empty()) return false;
    if (b.empty()) return true;
    for (int i = a.size() - 1; i >= 0; i--) {
        if (a[i] != b[i]) return a[i] < b[i];
    }
    return false;
}

// 深度优先搜索寻找最优解
bool dfs(int depth, LL a, LL b, LL from) {
    if (depth == max_depth) {
        if (a != 1) return false;
        if (b < from) return false;
        temp_d.push_back(b);
        if (better(temp_d, ans_d)) {
            ans_d = temp_d;
        }
        temp_d.pop_back();
        return true;
    }

    bool found = false;
    from = max(from, (b + a - 1) / a); // 计算k的下界
    for (LL k = from; ; k++) {
        // 剪枝:如果剩余的深度无法达到更好的解
        LL max_remaining = b * (max_depth - depth + 1);
        if (k > max_remaining) break;

        LL new_a = a * k - b;
        LL new_b = b * k;
        if (new_a <= 0) continue;

        pair<LL, LL> reduced = reduce(new_a, new_b);
        LL na = reduced.first;
        LL nb = reduced.second;
        
        temp_d.push_back(k);
        if (dfs(depth + 1, na, nb, k + 1)) {
            found = true;
        }
        temp_d.pop_back();
    }
    return found;
}

int main() {
    LL a, b;
    cin >> a >> b;

    pair<LL, LL> reduced = reduce(a, b);
    a = reduced.first;
    b = reduced.second;

    for (max_depth = 1; ; max_depth++) {
        temp_d.clear();
        if (dfs(1, a, b, (b + a - 1) / a)) {
            break;
        }
    }

    sort(ans_d.begin(), ans_d.end());
    for (vector<LL>::iterator it = ans_d.begin(); it != ans_d.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}    

相关文章:

  • Python爬虫进阶:Scrapy框架与异步编程深度实践
  • 解决el-input输入框输入数组传参报错
  • chrome打不开axure设计的软件产品原型问题解决办法
  • 华为OD机试真题——构成正方形的数量(2025B卷:100分)Java/python/JavaScript/C++/C/GO六种最佳实现
  • Vue.nextTick 异步更新队列:确保 DOM 更新后的操作
  • Halcon仿射变换---个人笔记
  • Git 初次推送远程仓库
  • HTML5 全面知识点总结
  • DEC Global:技术赋能如何重塑投资者决策模式?
  • 企业网站架构部署与优化-Nginx性能调优与深度监控
  • 「Python教案」判断语句的使用
  • Solr搜索:比传统数据库强在哪?
  • 大模型训练中的GPU作用解析
  • python训练营第35天
  • DAY12打卡 启发式算法
  • 华润电力招聘认知能力测评及性格测评真题题库考什么?
  • yolov8,c++案例汇总
  • 2025 河北ICPC( D. 金泰园(二分)-- C.年少的誓约(公式转化))
  • CentOS7安装 htop(100% 可以安上)
  • 【前端】Proxy对象在控制台中惰性求值_vue常见开发问题
  • 哪个网站做淘宝客/淘宝网店的seo主要是什么
  • 佛山做外贸网站推广/网络营销五种方法
  • delphi 做直播网站/郑州seo外包
  • 美国惠尔润滑油官方网站/怎么快速优化关键词排名
  • 设计网站建设图片/营销型网站建站推广
  • 四川住房建设厅网站/百度公司招聘岗位