第十一天:不定方程求解

每日一道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
英文地址,請注明出處:http://en.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方…