2023.7.26(同余方程的通解与特解)

Water(扩欧求特解与通解)

题意:给容量分别为A与B的水杯,问确切喝到C水的最小操作次数

有4种操作:选一杯全喝,选一杯全部倒掉,选一杯装满,将一杯的水尽量倒到另一杯中

思路:只有Ax+By=C有解时才能确切喝到X水

裴蜀定理:如果a、b是整数,那么一定存在整数x、y使得ax+by=k*gcd(a,b)。

思路:要求x,y的特解,可以使用exgcd的板子,令c = k * gcd(A, B)则Ax + By = c;exgcd求出来的是k = 1时的特解

只要将x *= c / gcd(A, B), y *= c / gcd(A, B);此时x和y就是方程Ax + By = c的特解

这里有一个步长的概念对于x他的步长是 B / gcd(A, B), 对于y他的步长是 A / gcd(A, B)

要求最小整数解,只需要把x除上他的步长就能知道x要走多少步才能最接近0,再把x -= 步长 * 步数就可以让x最接近0,然

后在对原点附近的 (x​+t⋅步长,y​−t⋅步长)求min⁡即可得到最小整数解

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
typedef pair<int, int> pr;

#define int long long
#define ll long long
#define fr(i,l,r) for(int i=l;i<=r;i++)
#define ufr(i,n,z) for(int i = n;i >= z; i--)
#define pb(x) push_back(x)
#define all(a) a.begin(),a.end()
#define fi first
#define se second

const int N = 1e6 + 10;
const int mod = 998244353, inf = LONG_LONG_MAX;
int dx[] = { 0,0,-1,0,1 }, dy[] = { 0,-1,0,1,0 };
int n, m;

int a[N];
int gcd(int a, int b) {         //辗转相除
    return !b ? a : gcd(b, a % b);
}
int exgcd(int a, int b, int& x, int& y)       //扩欧板子
{
    if (b == 0) {
        x = 1; y = 0;
        return a;  //到达递归边界开始向上一层返回
    }
    ll d = exgcd(b, a % b, y, x);
    y -= (a / b) * x;
    return d;
}
void solve()
{
    int a, b, c;
    cin >> a >> b >> c;
    if (c % gcd(a, b) != 0) {
        cout << -1 << '\n';                  //无解
    }
    else {
        int x, y;
        int d = exgcd(a, b, x, y);
        x *= c / d; y *= c / d;                    //特解(除去最大公约数乘上C)
        int dx = b / d; int dy = a / d;
        y += (x / dx) * dy;
        x -= (x / dx) * dx;       //最小整数解,只需要把x除上他的步长就能知道x要走多少步才能最接近0
        int ans = inf;
        fr(i, -10, 10) {
            int xx = x + dx * i; int yy = y - dy * i;           //通解
            ans = min(ans, max((xx + yy) << 1, (abs(xx - yy) << 1) - 1));
        }
        cout << ans << '\n';
    }
}

signed main()
{
    //    ios;
    int t = 1;
    cin >> t;
    while (t--) solve();
    return 0;
}

P1082 NOIP2012 提高组 同余方程

题意:求ax->1(mod b)的最小整数解,输入数据保证一定有解。

转变为ax=1+by,移项ax-by=1,

扩欧求的特解x/d,y/d,

通解x/d-i*(x/d/b/d)*b/d->x/d-x/b*(b/d)->x/d-i*x/d

cpp 复制代码
#include<iostream>
#define int long long
using namespace std;
int exgcd(int a, int b, int& x, int& y) {
    if (b == 0) {
        x = 1, y = 0;
        return a;
    }
    int d = exgcd(b, a % b, y, x);
    y -= (a / b) * x;
    return d;
}
signed main(){
    int a, b;
    int x, y;
    cin >> a >> b;
    exgcd(a, b, x, y);
    cout << (x % b + b) % b << '\n';
    return 0;
}
相关推荐
2501_915909069 分钟前
Windows 打开 Xcode 工程,编译调试 Xcode 项目并和 Mac 同事协作
ide·windows·vscode·macos·ios·个人开发·xcode
请为小H留灯9 小时前
Mac 常用操作与维护技巧
macos·电脑·清理电脑·常用技巧
hantmac19 小时前
不记得文件名时,Mac 上的搜索还能怎么做?
人工智能·macos
这是谁的博客?19 小时前
AI 加速器 RTL 数字系统设计深度解析:从 MAC 阵列 Verilog 实现到时序收敛与时钟功耗的芯片落地全链路
人工智能·macos·ai·verilog·数字ic设计·ai芯片·rtl
slacker-kian19 小时前
M 系列 Mac 清除顽固的 CorpLink
macos·corplink·m系列
2501_916007471 天前
Windows OpenSSL 生成 iOS 证书,制作 p12 与描述文件,KXBuild 签名实操
windows·vscode·ios·objective-c·个人开发·swift·敏捷流程
kk_net88991 天前
FSNotes:macOS 和 iOS 上的开源笔记管理器
笔记·其他·macos·ios
00后程序员张1 天前
Windows 开发 iOS App 入门,用 SwiftUI 写第一个 iOS App 装到 iPhone
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
zhangfeng11331 天前
com.apple.quarantine 并不是乱码,而是 macOS Gatekeeper 给下载文件自动打上的“隔离属性
macos·策略模式
甘晴void2 天前
我给 Magpie 做了个 macOS 桌宠:106 段动画,请求一多就亮灯
macos·electron·开源·deepseek·桌面宠物·magpie