第十一天:不定方程求解

每日一道C++题:不定方程求解

问题:给定正整数a,b,c。求不定方程 ax+by=c 关于未知数x和y的所有非负整数解组数。
要求:输入一行,包含三个正整数a,b,c,两个整数之间用单个空格开,每个数均不大于1000。输出一个整数,即不定方程的非负整数解组数。

求解不定方程的核心思路——枚举与优化

  • 暴力枚举的原始思路:
    因为 x 和 y 都是非负整数,所以对于 x 来说,它的取值范围可以初步确定为 0 =<x =<c / a (当 y = 0 时, x 能取到的最大值 );同理, y 的取值范围是 0 =<y =< c / b (当 x = 0 时 )。最直接的做法就是遍历 x 所有可能的取值,然后对于每个 x ,计算 c - ax 看是否能被 b 整除,且得到的 y = (c - ax) / b 也是非负整数。

例如题目中的输入样例 2 3 18 , a = 2 , b = 3 , c = 18 。 x 的可能取值是 0 到 18/2 = 9 。当 x = 0 时, 18 - 20 = 18 , 18 / 3 = 6 , y = 6 是整数且非负,这是一个解;当 x = 3 时, 18 - 23 = 12 , 12 / 3 = 4 , y = 4 有效,以此类推,遍历完所有 x 后统计符合条件的解的个数。

  • 枚举的优化方向:
    上述暴力枚举在 a 很小(比如 a = 1 )且 c 很大(比如 c = 10^9 )时,会导致循环次数极大,效率极低。所以后续我们可以结合数论知识(像贝祖定理、通解公式 )来优化,减少不必要的枚举。对于 x ,其可能的最大值为 c // a (当 y = 0 时);对于 y ,其可能的最大值为 c // b (当 x = 0 时)。这样可以减少不必要的枚举。
#include <iostream>
using namespace std;int main() {int a, b, c;cin >> a >> b >> c;int count = 0;// 枚举x的可能取值,x是非负整数,最大可能为c/a(当y=0时)for (int x = 0; x <= c / a; ++x) {// 计算剩余需要由by满足的值int remainder = c - a * x;// 检查remainder是否能被b整除,且y是非负整数if (remainder >= 0 && remainder % b == 0) {int y = remainder / b;// 确保y是非负整数if (y >= 0) {++count;}}}cout << count << endl;return 0;
}

通过 for 循环枚举 x 的可能取值,范围是从 0 到 c // a (确保 ax 不超过 c )。对于每个 x ,计算剩余需要满足的值 remainder = c - a * x 。检查 y 的合法性:如果 remainder 是非负的,并且能被 b 整除,则计算对应的 y 值,并检查 y 是否为非负整数。统计解的个数:如果找到合法的 y ,则增加解的计数器 count 。

问题拓展

  1. 贝祖定理

核心结论:
不定方程 ax + by = c 有解的充要条件是 gcd(a, b) |c (即 c 是 a 和 b 最大公约数的倍数 )。

在原问题基础上,先判断是否有解,再输出解的个数。

#include <iostream>
using namespace std;// 欧几里得算法求最大公约数
int gcd(int a, int b) {while (b != 0) {int temp = b;b = a % b;a = temp;}return a;
}int main() {int a, b, c;cin >> a >> b >> c;int g = gcd(a, b);// 先判断是否有解if (c % g != 0) {cout << 0 << endl; // 无解return 0;}// 有解时,转化为等价方程a /= g;b /= g;c /= g;int count = 0;// 枚举x的可能取值,注意范围变化for (int x = 0; x <= c / a; ++x) {int remainder = c - a * x;if (remainder >= 0 && remainder % b == 0) {int y = remainder / b;if (y >= 0) {++count;}}}cout << count << endl;return 0;
}
  • 让代码更严谨,避免无效枚举(比如输入 a=2, b=4, c=5 时直接判断无解 )。
  1. 通解公式与解的结构
  • 不定方程的通解可表示为:
    若 (x0, y0) 是一组特解,则所有解为:
    x = x0 + b/gcd(a,b) *t
    y = y0 - a/gcd(a,b) * t
    ( t 为整数,需保证 x >=0, y >=0 )

  • 扩展欧几里得算法不仅能求最大公约数,还能找到满足 ax + by = gcd(a,b) 的一组整数解 (x0, y0) 。当原方程 ax + by = c 有解时(即 gcd(a,b) | c ),我们可以先将方程两边除以 gcd(a,b) 得到等价方程,再利用扩展欧几里得算法找到特解,然后通过乘以相应系数得到原方程的特解。

  • 扩展题目:输出所有非负整数解的具体形式(不止个数,还要列出 (x,y) 对 )。

#include <iostream>
#include <vector>
using namespace std;int gcd(int a, int b) {while (b != 0) {int temp = b;b = a % b;a = temp;}return a;
}// 扩展欧几里得算法求特解
void extendedGcd(int a, int b, int& g, int& x0, int& y0) {if (b == 0) {g = a;x0 = 1;y0 = 0;} else {extendedGcd(b, a % b, g, y0, x0);y0 -= (a / b) * x0;}
}int main() {int a, b, c;cin >> a >> b >> c;int g = gcd(a, b);if (c % g != 0) {cout << 0 << endl;return 0;}a /= g;b /= g;c /= g;int x0, y0;extendedGcd(a, b, g, x0, y0); // 求特解// 特解调整到非负(通解的基础)x0 *= c;y0 *= c;vector<pair<int, int>> solutions;// 通解参数t的范围:保证x>=0, y>=0int t_min, t_max;// x = x0 + b*t >= 0t_min = ceil((-x0) / (double)b);// y = y0 - a*t >= 0t_max = floor(y0 / (double)a);for (int t = t_min; t <= t_max; ++t) {int x = x0 + b * t;int y = y0 - a * t;if (x >= 0 && y >= 0) {solutions.emplace_back(x, y);}}// 输出解的个数和具体解cout << solutions.size() << endl;for (auto& p : solutions) {cout << "(" << p.first << ", " << p.second << ")" << endl;}return 0;
}
  • 从“计数”升级到“找所有解”,理解不定方程解的结构。
  1. 数学推导优化

利用通解公式,直接计算 t 的范围,避免枚举 x :

  • 用扩展欧几里得找到特解 (x_0, y_0) 。
  • 推导 t 的取值范围,使得 x \geq 0, y \geq 0 。
  • 解的个数 = t_{\text{max}} - t_{\text{min}} + 1 (若有解 )。
#include <iostream>
#include <cmath>
using namespace std;int gcd(int a, int b) {while (b != 0) {int temp = b;b = a % b;a = temp;}return a;
}void extendedGcd(int a, int b, int& g, int& x0, int& y0) {if (b == 0) {g = a;x0 = 1;y0 = 0;} else {extendedGcd(b, a % b, g, y0, x0);y0 -= (a / b) * x0;}
}int main() {int a, b, c;cin >> a >> b >> c;int g = gcd(a, b);if (c % g != 0) {cout << 0 << endl;return 0;}a /= g;b /= g;c /= g;int x0, y0;extendedGcd(a, b, g, x0, y0);x0 *= c;y0 *= c;// 计算t的范围// x = x0 + b*t >= 0 --> t >= ceil( (-x0)/b )// y = y0 - a*t >= 0 --> t <= floor( y0/a )int t_min = ceil( (-x0) / (double)b );int t_max = floor( y0 / (double)a );// 解的个数int count = 0;if (t_min <= t_max) {count = t_max - t_min + 1;}cout << count << endl;return 0;
}

实际场景迁移:资源分配问题

  1. 场景 1:货币兑换

问题描述:
用面值为 a 和 b 的硬币,凑出金额 c ,有多少种非负整数组合?

对应模型:
ax + by = c 的非负整数解个数,直接对应本题。

  1. 场景 2:任务调度

问题描述:
机器 A 每小时处理 a 个任务,机器 B 每小时处理 b 个任务,要处理 c 个任务,有多少种非负整数时间分配方案?

对应模型:
ax + by = c ,其中 x 是机器 A 的工作时间, y 是机器 B 的工作时间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/91167.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/91167.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ElasticStack技术栈概述及Elasticsearch8.2.2集群部署并更换JDK版本为openjdk-17

ElasticStack 一、引言 在当今数据驱动的时代&#xff0c;如何高效地收集、处理和分析日志及其他类型的数据&#xff0c;已成为企业构建可观测性和运维能力的重要课题。Elastic Stack&#xff08;早期称为 ELK Stack&#xff09;是一套由 Elastic 公司推出的开源技术栈&#xf…

Doris中文检索效果调优

一、问题描述 原来的日志系统使用的是ES作为底层存储&#xff0c;后来因为数据量大了之后&#xff0c;出现了写入存在阻塞和查询效率变低的问题。后来决定切换到Doris数据库。 Doris的优势根据公开资料来看&#xff0c;它在写入性能、查询效率和存储成本上&#xff0c;都优于…

CDN怎么加速跟防御网站攻击呢?

**CDN&#xff08;内容分发网络&#xff09;**通过分布式架构和智能路由技术&#xff0c;不仅可以加速网站内容访问&#xff0c;还能有效防御多种网络攻击&#xff08;如DDoS、SQL注入等&#xff09;。以下是 CDN 如何实现加速和防御的详细解析&#xff1a;1. CDN 如何加速网站…

【Linux】批量处理多个用户的 sudo 权限问题

要批量处理多个用户的 sudo 权限问题&#xff0c;有以下几种高效方法&#xff1a; 方法一&#xff1a;通过用户组批量授权&#xff08;推荐&#xff09; 这是最安全便捷的方式&#xff0c;只需将用户加入已有 sudo 权限组&#xff08;如 wheel 或 sudo&#xff09;&#xff1a;…

云原生MySQL Operator开发实战(五):扩展与生态系统集成

引言 在前四篇文章中,我们构建了一个功能完备的MySQL Operator,涵盖了从基础架构到生产部署的全过程。本文将作为本系列的收官之作,重点探讨Operator的扩展能力和与云原生生态系统的深度集成,包括自定义插件系统、与CI/CD流水线的集成、服务网格支持以及与云服务的无缝对接…

【MySQL】数据库的简单介绍

1.数据库是什么简单来说&#xff0c;数据库是用于存储数据和管理数据的软件。数据库可以提供远程服务&#xff0c;通过远程连接来使用数据库&#xff0c;因此数据库也被称为数据库服务器&#xff01;2.为什么要使用数据库存储数据用文件就可以了&#xff0c;为什么还要弄一个数…

uniapp,uview icon加载太慢了,老是显示叉叉,将远程加载改到本地加载。

处理方式&#xff1a;将远程字体文件下载到本地进行加载。app.vue。font-face {font-family: uicon-iconfont;src: url(./static/fonts/font_2225171_8kdcwk4po24.ttf) format(truetype);font-weight: normal;font-style: normal;}下载文件&#xff1a;从node_modules找文件u-i…

Python爬虫01_Requests第一血获取响应数据

引入requests包&#xff0c;发起请求并获取响应数据。 import requestsif __name__ "__main__":#step 1&#xff1a;指定urlurl http://www.7k7k.com/#step 2&#xff1a;发起请求&#xff0c;get方法会返回一个响应对象response requests.get(url)#step 3&#x…

Linux定时器和时间管理源码相关总结

基础可参考&#xff1a; Linux内核定时器相关内容总结-CSDN博客 定时器来源 定时器也是来源于芯片的硬件定时器&#xff0c;属于内部外设&#xff0c;有些可能也会用外部定时器&#xff0c;不管咋样&#xff0c;都属于芯片外设&#xff0c;既然是外设&#xff0c;那么我们也要编…

JDK17 新特性跟学梳理

JDK17 新特性跟学梳理JDK17 背景介绍一、JDK 17对Switch语句的增强二、字符串拼接三、强制转换四、密封类Sealed Classes五、Record类六、优化空指针异常信息七、ZGC垃圾收集器八、JVM常量API九、重写Socket底层API十、JDK飞行记录事件流十一、EdDSA签名算法十二、隐藏类十三、…

ESP8266 AT 固件

ESP-12E 是一种常见的 ESP8266 模块&#xff0c;通常带有 4MB&#xff08;32Mbit&#xff09;闪存&#xff0c;非常适合刷写 最新版 AT 固件。 ✅ 适用于 ESP‑12E 的 AT 固件推荐 固件来源固件版本特点Espressif 官方v2.2.1.0 (ESP8266 IDF AT)官方最新版&#xff0c;基于 RT…

Node.js(三)之Express

Express 目录 Express 九、初识Express 9.1 Express简介 1. 什么是 Express 2. 进一步理解Express 3. Express能做什么 9.2 Express的基本使用 1. 安装 2. 创建基本的Web服务器 3. 监听GET请求 4. 监听POST请求 5. 把内容响应给客户端 6. 获取URL中携带的查询参数…

IKAnalyzer分词插件使用方法

前言 随着越来越多的大数据网站崛起&#xff0c;特别是一些私人网站都提供了站内搜索&#xff0c;有些人会用elastsearch来实现站内搜索的目的&#xff0c;但是一些小站并没有那么大的数据提供搜索&#xff0c;在安装一个 elastsearch 服务未免有点浪费&#xff1f; 因此&#…

ESB 在零售,物流,制造,保险,医疗行业的应用方式

企业服务总线&#xff08;Enterprise Service Bus, ESB&#xff09;是一种基于中间件的集成模式&#xff0c;用于实现不同系统之间的集成与通信。ESB通过标准化接口、消息路由、协议转换和数据转换等功能&#xff0c;帮助企业实现系统间的无缝对接&#xff0c;提高业务敏捷性。…

vcsa6.7-重置root密码

客户反馈vc无法登录了&#xff0c;登录环境一看&#xff0c;报错如下首先想到是证书到期了&#xff0c;浏览器确认&#xff0c;确实是证书到期了准备ssh登录才发现root密码忘记了&#xff0c;那就先重置root密码&#xff0c;1、登录esxi主机找到vcsa6.7机器关机做快照2、开机到…

C++ 赋值与交换法则

在C中&#xff0c;赋值与交换法则&#xff08;Assignment and Swap Idiom&#xff09;通常指的是在实现类的赋值操作符&#xff08;operator&#xff09;时&#xff0c;结合拷贝构造和交换操作来确保强异常安全保证&#xff08;Strong Exception Safety Guarantee&#xff09;的…

Ambari中文汉化

Ambari-ZH 当前Ambari的汉化版本为2.7.4,汉化采用对该版本的ambari源码直接修改的方式进行,如有翻译不当之处,请批评指正 一、使用方法如下&#xff1a; 方式一&#xff1a;直接下载 下载地址&#xff1a;https://github.com/ukayunnuo/Ambari-2.7.x-zh/releases/download/…

表格之固定列和表头

说明 利用粘性定位实现 列固定 td.fixed {position: sticky;left: 0;z-index: 5;/* 最好指定背景&#xff0c;否则滑动时会显示下面的列 */background-color: #f8f9fa; }表头固定 <head><style>.table-container {position: relative;display: flex;overflow: hidd…

React 图标库发布到 npm 仓库

将搭建的 React 图标库发布到 npm 仓库需要经过一系列步骤&#xff0c;包括配置 package.json、构建代码、注册 npm 账号、测试和发布。以下是详细流程&#xff1a; 1. 准备工作 (1) 确保项目结构完整 图标库的典型结构&#xff08;以 Rollup 构建为例&#xff09;&#xff1…

Java学习第八十四部分——HttpClient

目录 一、前言介绍 二、主要特点 三、功能用法 四、应用场景 五、最佳实践 六、总结归纳 一、前言介绍 HttpClient 是一个用于发送 HTTP 请求和接收 HTTP 响应的客户端库&#xff0c;广泛应用于 Web 开发、API 调用、微服务通信等场景。 二、主要特点 支持多种HTTP方…