hdu 2669 Romantic (扩展欧几里得)
来源:互联网 发布:zencart 建站 编辑:程序博客网 时间:2024/05/26 02:54
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2669
题意:求线性方程a*x + b*y = c的一组整数解,其中c=1,并要求x非负。
解题方案:扩展欧几里得。若gcd(a,b)!=1,则c不是gcd(a,b)的倍数,则无解。所以如果有解,则gcd(a,b)==1,即原方程可转换为a*x + b*y = gcd(a,b)。
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <vector>#include <queue>#include <stack>#include <set>#include <map>using namespace std;#define FOR(i,k,n) for(int i=k;i<n;i++)#define FORR(i,k,n) for(int i=k;i<=n;i++)#define scan(a) scanf("%d",&a)#define scann(a,b) scanf("%d%d",&a,&b)#define scannn(a,b,c) scanf("%d%d%d",&a,&b,&c)#define mst(a,n) memset(a,n,sizeof(a))#define ll long long#define N 1005#define mod 1000000007#define INF 0x3f3f3f3fconst double eps=1e-8;const double pi=acos(-1.0);ll ex_gcd(ll a,ll b,ll &x,ll &y)//a*x+b*y=gcd(a,b){ if(b==0) { x=1; y=0; return a; } ll d=ex_gcd(b,a%b,x,y); ll xx=x; x=y; y=xx-a/b*y; return d;}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); ll a,b; while(cin>>a>>b) { ll x,y; ll d=ex_gcd(a,b,x,y); if(d==1) { while(x<0)//a(x+b)+b(y-a)=ax+by=1 { x+=b; y-=a; } printf("%lld %lld\n",x,y); } else printf("sorry\n"); } return 0;}
将取x非负解的时候的复杂度降到O(1),参考代码:扩展欧几里得算法详解
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <vector>#include <queue>#include <stack>#include <set>#include <map>using namespace std;#define FOR(i,k,n) for(int i=k;i<n;i++)#define FORR(i,k,n) for(int i=k;i<=n;i++)#define scan(a) scanf("%d",&a)#define scann(a,b) scanf("%d%d",&a,&b)#define scannn(a,b,c) scanf("%d%d%d",&a,&b,&c)#define mst(a,n) memset(a,n,sizeof(a))#define ll long long#define N 1005#define mod 1000000007#define INF 0x3f3f3f3fconst double eps=1e-8;const double pi=acos(-1.0);ll ex_gcd(ll a,ll b,ll &x,ll &y)//a*x+b*y=gcd(a,b){ if(b==0) { x=1; y=0; return a; } ll d=ex_gcd(b,a%b,x,y); ll xx=x; x=y; y=xx-a/b*y; return d;}ll cal(ll a,ll b,ll c)//a*x+b*y=c中x的最小正整数解{ ll x,y; ll gcd=ex_gcd(a,b,x,y);//得到a*x+b*y=gcd(a,b)的解 if(c%gcd!=0) return -1; x*=c/gcd;//得到a*x+b*y=c①的解x b/=gcd;//为得到x的最小正整数解,将方程①化为等价的a'*x+b'*y=c'②(等式两边同除以gcd),解不变 //在本题中这句可以去掉,本题只要求x非负即可 if(b<0) b=-b;//为取模方便,当b为负数时,将方程②化为等价的a''*x+b''*y=c''③(等式两边同乘以-1),解不变 //在本题中这句可以去掉,本题b>0 ll ans=x%b;//当x>0时,此时直接取到x的最小正整数解;当x<=0时,对b取模后再加b可得x的最小正整数解 if(ans<=0) ans+=b; return ans;}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); ll a,b; while(cin>>a>>b) { ll ans=cal(a,b,1); if(ans!=-1) printf("%lld %lld\n",ans,(1-a*ans)/b); else printf("sorry\n"); } return 0;}
0 0
- hdu - 2669 - Romantic(扩展欧几里得)
- 【HDU】2669 - Romantic(扩展欧几里得)
- HDU 2669:Romantic(扩展欧几里得)
- 【hdu 2669】Romantic(扩展欧几里得)
- hdu 2669 Romantic (扩展欧几里得)
- HDU 2669 Romantic 扩展欧几里得
- HDU 2669 Romantic(扩展欧几里得)
- HDU 2669 Romantic (扩展欧几里得)
- hdu 2669 Romantic 扩展欧几里得
- HDU 2669 Romantic [扩展欧几里得]
- HDU 2669 Romantic扩展欧几里得
- 扩展欧几里得 Romantic (HDU
- hdu 2669 Romantic(线性同余,扩展欧几里得)
- HDU 2669 Romantic (扩展欧几里得定理)
- [数论]HDU 2669 Romantic 扩展欧几里得算法
- HDU 2669 Romantic 扩展欧几里得模板题@
- HDU 2669 Romantic【扩展欧几里得板子题】
- Romantic(扩展欧几里得)
- 【bzoj2327】[HNOI2011]勾股定理
- 在Eclipse中使用JUnit4进行单元测试(初级篇)
- Notification回顾
- 1016. 部分A+B (15)
- iOS10通知(一)--申请授权、注册和获取授权信息
- hdu 2669 Romantic (扩展欧几里得)
- mybatis # $区别
- 嵌入式和单片机的关系
- material design(一)CardView的使用详解
- 程序员如何更好的活着
- UIScrollView 非常规的page 实现
- OSG学习笔记24——根据鼠标平移的位置正确设置物体平移量
- MySQL数据库消耗CPU过高
- 【生成器】用generator生成杨辉三角