UVALive 6428 A+B 【扩展欧几里得】

news/2023/12/10 15:30:15

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4439

题目大意:给出a,b,S三个数,每次可以选择从a的位置加到b上,也可以从b的位置加到a上,问a或者b的位置上能否达到S。

   比如:给出a和b,可以得到的是

    (a b) 

  (a+b b) (a a+b) 

      (a+2b b)   (a+b a+2*b)     (2a+b a+b)      (a 2a+b)

......

    只要符合上面的a和b的系数关系即可。

推了三行,发现了系数x和y只要满足gcd(x,y)==1即可。

然后就RE了,读题不细心:a,b,S的范围是[ 0~10^18 ]。 除了0,导致了RE。

后来就一直WA,为啥呢..........

用的扩展欧几里得求不定方程的解的模板:

LL gcd(LL a,LL b){if(b==0) return a;else return gcd(b,a%b);
}LL ex_gcd(LL a,LL b,LL &x,LL &y){if(b==0){x=1;y=0;return a;}LL r=ex_gcd(b,a%b,x,y);LL t=x;x=y;y=t-a/b*y;return r;
}//求解ax+by=c的解x,y x,y需要提前定义
bool linear_equation(LL a,LL b,LL c,LL &x,LL &y)
{LL d=ex_gcd(a,b,x,y);if(c%d!=0)   //即不整除return false;LL k=c/d;x*=k; y*=k;    //求得的只是其中一组解,另外的解是:x+b/gcd(a,b)*i y-a/gcd(a,b)*ireturn true;
}

注意最后三行,x=x*c/d。

而最后我要求一个x的最小的值。

用了(x%B+B)% B

所以来说就是(x*c/d)% B  而这个值就是有可能爆LL。所以一直wa。

要变成   x = (x%B)* (c / d %B)

#include<iostream>
#include<stdio.h>
using namespace std;
#define LL long longLL gcd(LL a,LL b){if(b==0) return a;else return gcd(b,a%b);
}LL ex_gcd(LL a,LL b,LL &x,LL &y){if(b==0){x=1;y=0;return a;}LL r=ex_gcd(b,a%b,y,x);y=y-a/b*x;return r;
}//求解ax+by=c的解x,y x,y需要提前定义
bool linear_equation(LL a,LL b,LL c,LL &x,LL &y)
{LL d=ex_gcd(a,b,x,y);if(c%d!=0)   //即不整除return false;//LL k=c/d;//x*=k; y*=k;    //求得的只是其中一组解,另外的解是:x+b/gcd(a,b)*i y-a/gcd(a,b)*ireturn true;
}int main (){LL a,b,S;while(~scanf("%lld%lld%lld",&a,&b,&S)){if(a==S||b==S)          {printf("YES\n");continue;}if(a==0&&b==0)          {printf("NO\n");continue;}if(a==0&&S%b==0)        {printf("YES\n");continue;}if(a==0&&S%b!=0)        {printf("NO\n");continue;}if(b==0&&S%a==0)        {printf("YES\n");continue;}if(b==0&&S%a!=0)        {printf("NO\n");continue;}int flag = 0;LL x,y;LL i = 1;LL g = gcd(a,b);if(linear_equation(a,b,S,x,y)) {//printf("%lld %lld\n",x,y);LL B = b/g;LL A = a/g;x = (S / g % B) * (x % B);x = (x % B + B) % B;y = (S - (x*a) )/b;while(1){if( y <= 0 ) {break;}if((x>0&&y>0&&gcd(x,y)==1)) {flag = 1; break;}x = x + B;y = y - A;//printf("%lld %lld\n",x,y);}}else{printf("NO\n"); continue;}if(flag==1) printf("YES\n");else printf("NO\n");}return 0;
}
/*
1 2 3
3 4 5
3 4 17
*/



https://dhexx.cn/news/show-39549.html

相关文章

Leetcode 516. 最长回文子序列 (区间dp)

经典的区间dp问题&#xff0c;f[i][j]表示字符串i到j组成的最长回文子序列的长度&#xff0c;由如下递推关系&#xff1a; 这种区间dp递推的时候&#xff0c;最外层循环是长度&#xff0c;从小区间递推到大区间。 class Solution { public:int longestPalindromeSubseq(strin…

Leetcode 312. 戳气球(经典区间dp)

为了避免边界问题&#xff0c;我们重新开一个数组&#xff0c;在两个端点加入哨兵1。此时数组下标为0到n1 状态的定义如下&#xff0c;f[i][j] 表示将区间[i1&#xff0c;j-1]的气球全部戳爆的最大收益。 我们要求的答案就是f[0][n1] 将1到n个气球全部戳爆的最大收益。 一般…

动手实现Sqlite(3) 手动实现数据insert过程

这里先对一个具体的表做实现&#xff0c;然后在想办法抽象成一般的表。 解析以及格式化提取内容部分 if (strncmp(input_buffer->buffer, "insert", 6) 0) {statement->type STATEMENT_INSERT;int args_assigned sscanf(input_buffer->buffer, "in…

【编程珠玑(续)】第二章 关联数组

一&#xff0c;关联数组 关联数组和数组类似&#xff0c;由以名称作为键的字段和方法组成。 它包含标量数据&#xff0c;可用索引值来单独选择这些数据&#xff0c;和数组不同的是&#xff0c; 关联数组的索引值不是非负的整数而是任意的标量。这些标量称为Keys&#xff0c;可以…

动手实现Sqlite(3) 思路分析

重点难点&#xff1a; 1. 理解内存中二进制连续数据存储&#xff0c;如何处理。 2. 理解Table数据结构和Page结构&#xff0c;以及对应的select和insert操作。 测试驱动开发&#xff0c;首先先看我们想要的结果 ~ ./db db > insert 1 cstack foobar.com Executed. db >…

Leetcode 220. 存在重复元素 III (set加滑动窗口优化)

直接做时间复杂度是O(N^2&#xff09; 预期优化到O(nlogn) 在遍历的过程中&#xff0c;维护k个元素的set&#xff0c;当元素个数大于k以后&#xff0c;就删掉nums[i - k]元素&#xff0c; 我们在log(N&#xff09;的时间找到第一个大于等于nums[i]-t元素&#xff0c;在看看他…

This tag and its children can be replaced by one TextView/ and a compound drawable

写了这么一段代码&#xff1a; <LinearLayout android:orientation"horizontal" android:layout_centerInParent"true" android:layout_height"wrap_content" android:layout_width"wrap_content"> <ImageView android:id&qu…

polay定理总结

参考资料&#xff1a;polay定理 感觉最近一直容易遇见这种题目....... 稍微复杂一点的就不太会 先是一个总结出来的定理&#xff1a; 用一个最简单的例子来说明 对2*2的方阵用黑白两种颜色涂色&#xff0c;问能得到多少种不同的图像&#xff1f;经过旋转使之吻合的两种方案…

Session那些事(一)

前一段时间做一个应用的客户端时&#xff0c;涉及到用户权限的问题&#xff0c;所以用到了Session&#xff0c;遇到一些问题&#xff0c;网上找了各位大神的一些资料&#xff0c;今天汇总到这&#xff0c;以便以后复习。 1.Session 由于HTTP协议连接的无状态性&#xff0c;才使…

Leetcode 507. 完美数 (数论简单题,时间复杂度优化到O(sqrt(n)))

将因子分成两部分。 class Solution { public:bool checkPerfectNumber(int num) {if(num < 1) return false;int n sqrt(num), tmp1 1, tmp2 0;for(int i 2; i < n; i){if(num % i 0){tmp1 i;if((i * i) ! num){tmp2 num / i;}}}return (tmp1 tmp2) num;} };