同余方程

同余方程

https://ac.nowcoder.com/acm/problem/16563

扩展欧几里得

PS: 算是初次接触数论吧,但是很有意思的是遇到了一个讲解很透彻的博客,几乎把我之前的疑惑都解释清楚了,再次特别感谢那位不知名的博主

1.首先这是一道裸的数论的题目,这个题目有很多地方需要细节处理,第一个就是溢出的问题,因为题目给的数据很大,如果用int去定义的话,两个int变量相乘很可能就会溢出int类型的范围了,(int类型的范围最大是2^31-1,相当于2e9的样子),所以如果担心越界那就用long long去定义变量,那如果非要用int去定义的话,就需要简单的处理一下,我们先让两个变量去相除得到的结果然后再去相乘,这样就解决的越界的问题了

2.题目要求要求最小正整数解,而我们使用这个算法可能会得出负数,为了防止这种情况出现,我们就要在得出结果的时候加上一个整数再去模这个整数,那么就可以得到一个最小正整数解了

3.首先解释一下平时在数学课本上不出现的符号≡,同余符号,含义为两个整数a,b,若它们除以整数m所得的余数相等,则称a,b对于模m同余,记作a≡b(mod m)。那么,同余方程ax ≡ 1 (mod b),如果转化为我们通俗易懂的语言就是->求满足ax%b=1,1%b=1最小正整数解。
那么接下来就可以使用扩展欧几里得解决了。

AC代码一:

#include <bits/stdc++.h>
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, x, y);
   int z = x;
   x = y;
   y = z - y * (a / b);
   return d;
}
int main()
{
   int a, b, x, y;
   scanf("%d%d", &a, &b);
   exgcd(a, b, x, y);
   printf("%d\n", (x + b) % b);
   return 0;
}

AC代码二:

#include <bits/stdc++.h>
using namespace std;
int a, b, k, x, y;
void exgcd(int a, int b)
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        return;
    }
    exgcd(b, a % b);
    k = x;
    x = y;
    y = k - a / b * y;
    return;
}
int main()
{
    scanf("%d%d", &a, &b);
    exgcd(a, b);
    printf("%d\n", (x + b) % b);
}
牛客课后习题题解 文章被收录于专栏

等待蜕变

全部评论

相关推荐

10-27 17:26
东北大学 Java
点赞 评论 收藏
分享
工作30年还房贷:比赛加学历就已经够了。你要挑点毛病的话,项目写的不行,没有突出深度,你可能做了很多深度工作,但给别人的感觉都是做的很简单的工作。
点赞 评论 收藏
分享
上海拼多多 算法工程师 总包54(好像是多多的算法白菜价 [笑cry]?)
sunrrrrise:多多太低了
点赞 评论 收藏
分享
评论
2
收藏
分享
牛客网
牛客企业服务