题解 CF7C 【Line】

本文详细介绍了扩展欧几里得算法的应用场景及其在解决不定方程、模线性方程等方面的具体实现方法。文章提供了算法的核心步骤,并附带了一个简单的C++实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这题一看就是扩欧水题(注意没学过扩欧那肯定就不是了,学过扩欧其实就是模板题),将此算式转换为Ax+By=-C即可,注意补充几个知识点(这几个知识点看完后可以自己写写代码,如果实在写不出来再来看代码,毕竟模板题记住就行了,但是还要理解):

扩展欧几里得算法:对于整数a,b,必定存在整数对x,y满足ax+by=gcd(a, b)

扩展欧几里得算法应用

1.不定方程ax+by=c无解判定:如果c%d==0有解,否则无解

2.求解不定方程ax+by=c:先用扩欧求出ax’+by’= d =gcd(a,b)的一组解x'和y',则方程原来的一组解为 x=x'c/d,y=y'c/d,通解为x=x'c/d+kb/d,y=y'c/d-ka/d(k为任意整数)

3.解模线性方程:a ≡ b (mod n)的含义是a和b关于模n同余,即a mod n==b mod n,则ax-b=ny,移项得ax-ny=b,这恰好是一个二元一次不定方程,用2解决。

4.乘法逆元:ax ≡ 1 (mod n)的解x称为a关于模n的乘法逆元。若gcd(a,n)=1有唯一解,反之无解。注意:通过扩欧算出的不定方程有很多解,最终的逆元应该是(x%n+n)%n,也就是逆元的范围是[0,n-1]

5.改写算式:(a/b) mod p == (a(b的逆元) ) mod p==((a mod p)((b的逆元) mod p)) mod p

至于证明就不再给出,毕竟LX说过:“证明是数竞选手的事,我们信竞看看,然后用就好了(百度一大堆感兴趣可自行搜索)。”

代码如下:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
long long kuoou(long long a,long long b,long long &x1,long long &y1)//地址符号注意
{
    long long x2,y2;
    if(b==0)
    {
        x1=1;
        y1=0;
        return a;
    }
    long long d=kuoou(b,a%b,x2,y2);
    x1=y2;
    y1=x2-a/b*y2;
    return d;
}
int main()
{
    long long a,b,c,x,y;
    scanf("%lld%lld%lld",&a,&b,&c);
    c=-c;
    long long d=kuoou(a,b,x,y);//这里面的x,y只是当ax+by==gcd(a,b)时候的解,还要在下面进行转换
    if(c%d!=0)
    {
        printf("-1");
        return 0;
    }
    x=x*c/d;
    y=y*c/d;//这两步
    //如果不是随机解而是限制解怎么办呢(比如最小解)?
    //那么我们就要用到循环并分类讨论,具体代码不在阐述
    printf("%lld %lld",x,y);
    return 0;
}

CF Directional Increase是一道经典的算法题目,通常出现在编程竞赛中。题目要求在一个二维网格中,找到从起点到终点的路径,使得路径上的数值递增。以下是详细的题解: ### 题目描述 给定一个二维网格,每个格子中有一个整数。起点在左上角,终点在右下角。你可以从当前格子移动到右边的格子或下边的格子。找到一条路径,使得路径上的数值递增。 ### 解题思路 1. **动态规划**:使用动态规划来解决问题。定义一个二维数组`dp[i][j]`,表示从起点到格子`(i, j)`的递增路径的长度。 2. **初始化**:起点`dp[0][0]`的值为`grid[0][0]`。 3. **状态转移方程**: - 如果从上方移动到当前格子`(i, j)`,则`dp[i][j] = max(dp[i][j], dp[i-1][j] + 1)`,前提是`grid[i][j] > grid[i-1][j]`。 - 如果从左方移动到当前格子`(i, j)`,则`dp[i][j] = max(dp[i][j], dp[i][j-1] + 1)`,前提是`grid[i][j] > grid[i][j-1]`。 ### 代码实现 ```python def directional_increase(grid): if not grid or not grid[0]: return 0 m, n = len(grid), len(grid[0]) dp = [[1] * n for _ in range(m)] for i in range(m): for j in range(n): if i > 0 and grid[i][j] > grid[i-1][j]: dp[i][j] = max(dp[i][j], dp[i-1][j] + 1) if j > 0 and grid[i][j] > grid[i][j-1]: dp[i][j] = max(dp[i][j], dp[i][j-1] + 1) return dp[m-1][n-1] # 示例 grid = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] print(directional_increase(grid)) # 输出: 5 ``` ### 解释 - 初始化`dp`数组为全1,因为每个格子的递增路径至少为1。 - 遍历每个格子,更新`dp[i][j]`的值。 - 最后,`dp[m-1][n-1]`即为从起点到终点的递增路径的最大长度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值