每日一题(2026.4.29) 猫猫与数学

题目


AC 代码

cpp 复制代码
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#define ll long long
using namespace std;

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

    ll d=abs(a-b);
    if(d==0)
    {
        if(a==1)
          cout<<1<<endl;
        else
          cout<<0<<endl;
        return 0;
    }

    if(d==1)cout<<-1<<endl;
    else
    {
        vector<ll> v;
        for(ll i=2;i*i<=d;i++)
        {
            if(d%i==0)
            {
                v.push_back(i);
                while(d%i==0)
                {
                    d=d/i;
                }
            }
        }
        if(d>1)v.push_back(d);

        ll ans = 1e18;
        for(auto& x:v)
        {
            ans=min(ans,(x-a%x)%x);
        }
        cout<<ans<<endl;
    }

    return 0;
}

个人见解

由题意,假设有一数字 ggg,令 A=a+c,B=b+cA = a + c,B = b + cA=a+c,B=b+c,我们希望得到 g∣Ag | Ag∣A 和 g∣Bg | Bg∣B ,即 ggg 整除 AAA 和 ggg 整除 BBB,因此有:
A=k1×g,B=k2×g↓∣A−B∣=(k1−k2)×g↓∣a−b∣=(k1−k2)×g A = k_1×g,B = k_2×g \\ ↓ \\ |A - B| = (k_1 - k_2)×g \\ ↓ \\ |a - b| = (k_1 - k_2)×g A=k1×g,B=k2×g↓∣A−B∣=(k1−k2)×g↓∣a−b∣=(k1−k2)×g

因此寻找因子的范围可以从无穷缩小为 2,∣a−b∣2,\|a - b\|2,∣a−b∣,并且题目有说当 gcdgcdgcd 为 111 时无解,因此可以通过上述公式推导出只有 ∣a−b∣=1|a - b| = 1∣a−b∣=1 的时候才会无解。

cpp 复制代码
if(d==0)
{
    if(a==1)
      cout<<1<<endl;
    else
      cout<<0<<endl;
    return 0;
}

这里的判断需要小心 a=b=1a=b=1a=b=1 的情况,此时只需要 +1+1+1 即可让 gcdgcdgcd 变成 222。

cpp 复制代码
if(d==1)cout<<-1<<endl;
else
{
    vector<ll> v;
    for(ll i=2;i*i<=d;i++)
    {
        if(d%i==0)
        {
            v.push_back(i);
            while(d%i==0)
            {
                d=d/i;
            }
        }
    }
    if(d>1)v.push_back(d);

    ll ans = 1e18;
    for(auto& x:v)
    {
        ans=min(ans,(x-a%x)%x);
    }
    cout<<ans<<endl;
}

这是代码的核心部分,如果 d==1d==1d==1 当然直接输出 −1-1−1。

否则,需要循环寻找 ddd 的因子,与普通寻找因数不同的是,本题只需要存储质因子,因为我们只想找到最小的 a+ca+ca+c 和 b+cb+cb+c。

cpp 复制代码
if(d%i==0)
{
    v.push_back(i);
    while(d%i==0)
    {
        d=d/i;
    }
}

因此,只要 d%i==0d \% i==0d%i==0 就直接推入 vector 容器,然后利用 whilewhilewhile 循环剔除所有因子 iii ,这也是在保证往后出现的 iii 一定是质因子的原因。

cpp 复制代码
if(d>1)v.push_back(d);

因为 ddd 的值在变化,可能会出现 d>1d>1d>1 但是 i∗i>di*i>di∗i>d 的情况,如果不加这行会遗漏关键的一个质因子!!!

cpp 复制代码
ll ans = 1e18;
for(auto& x:v)
{
    ans=min(ans,(x-a%x)%x);
}

这里就是在寻找最小 ccc 的过程了,注意这里的表达式 (x−a%x)%x(x-a\%x)\%x(x−a%x)%x。
a%xa\%xa%x 表示aaa 大出 xxx 的数值,而 x−a%xx-a\%xx−a%x 表示距离凑出下一个 xxx 的倍数需要补齐的数字,那么为什么要再对 xxx 取模呢?举个例子,如果a==x,a%x==0a == x,a\%x==0a==x,a%x==0 ,此时 x−a%x==xx-a\%x == xx−a%x==x,但真实情况是由于 aaa 可以整除 xxx,所以xxx 此时不需要补齐任何数字,因此最后再对 (x−a%x)(x-a\%x)(x−a%x) 进行取模,即 (x−a%x)%x(x-a\%x)\%x(x−a%x)%x 。

相关推荐
搬砖魁首12 分钟前
基础能力系列 - 多线程2 - 条件变量
c++·rust·条件变量·原子类型·线程同步互斥
youngerwang18 分钟前
【从搬运工到协处理器:网卡芯片架构、算法、验证与边缘演进深度剖析】
网络·算法·架构·芯片
chase_my_dream20 分钟前
C++ + SLAM 高频面试问题整理
开发语言·c++·面试
牛油果子哥q41 分钟前
【C++ STL string 】C++ STL string 终极精讲:底层原理、内存机制、全套API、深浅拷贝、易错坑点与工程实战规范
数据库·c++
KaMeidebaby42 分钟前
卡梅德生物技术快报|纯化重组蛋白实操详解
人工智能·python·tcp/ip·算法·机器学习
caimouse43 分钟前
Reactos 第 5 章 进程与线程 — 5.8 Windows 的 APC 机制
c语言·windows
手写码匠2 小时前
从零实现 Prompt 工程引擎:结构化提示、自动优化与多轮自省体系
人工智能·深度学习·算法·aigc
无限码力2 小时前
阿里算法岗 0530笔试真题 - 多约束条件下的元素匹配统计
算法·阿里笔试真题·阿里机试真题·阿里算法岗笔试
lqqjuly2 小时前
MLA — 多头潜在注意力深度解析
深度学习·神经网络·算法
吴可可1232 小时前
SolidWorks草图转三维DWG技巧
算法