hdu_4180 RealPhobia (扩展欧几里德)
来源:互联网 发布:游戏宣传片制作软件 编辑:程序博客网 时间:2024/05/29 17:38
http://acm.hdu.edu.cn/showproblem.php?pid=4180
题意:
给一个真分数A/B,求C/D,D<B并且fabs(A/B-C/D)最小(即两个分数距离最近)思路:
要求|a/b-c/d|最小,先通分得|(a*d-b*c)/(b*a)|,使其最小,分母为最小莫过于为1,(为0的话表示可以约分,直接输出约分后的分数)。
分母尽可能大。
a*d-b*c=1或者b*c-a*d=1...#
由扩展欧几里德
a*x+b*y=gcd(a,b);
所以 d=x,c=-y 或者 c=y,d=-x
由#式可得a(d+b)-b(c+a)=1或者b(c+a)-a(d+b)=1
可解得 d=x+b,c=-y+a 或者 c=y+a,d=-x+b; //这里要取模,目的是把分子分母变成正数
最后输出分母大的一组。(因为b*a会更大)
PS:这题DT了好久,暴力超时,搜索连分数也不好做。。。
我的代码:
/*program:hdu4180,hnu12445author:BlackAndWhite*/ #include<stdio.h>__int64 T,a,b;__int64 x,y,gcd,c1,d1,c2,d2;__int64 extended_gcd(__int64 a,__int64 b,__int64 &x,__int64 &y){ __int64 ans,t; if (b==0) { x=1; y=0; return a; } else { ans=extended_gcd(b,a%b,x,y); t=x; x=y; y=t-(a/b)*y;} return ans;}int main(){ scanf("%I64d",&T); while(T--) { scanf("%I64d/%I64d",&a,&b); gcd=extended_gcd(a,b,x,y); if(gcd!=1){printf("%I64d/%I64d\n",a/gcd,b/gcd);continue;} if(a==1){printf("1/%I64d\n",b-1);continue;} d1=(x+b)%b; c1=(-y+a)%a; c2=(y+a)%a; d2=(-x+b)%b; if(d1<d2) printf("%I64d/%I64d\n",c2,d2); else printf("%I64d/%I64d\n",c1,d1); } return 0;}
- hdu_4180 RealPhobia (扩展欧几里德)
- HDU 4180_ RealPhobia (扩展欧几里德定理)
- HDU 4180 RealPhobia(扩展欧几里得)
- 欧几里德和扩展欧几里德
- 欧几里德, 与 扩展欧几里德
- 欧几里德|扩展欧几里德
- 欧几里德&&扩展欧几里德详解
- 欧几里德&&扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德!!!!!
- wince MFC调试问题总结
- C++ 智能指针
- 【二分图匹配】 hdu3605 Escape
- 获取 请求方 mac 地址
- 安装两个BCB6控件SynEdit、mwEdit 0.92a的过程总结
- hdu_4180 RealPhobia (扩展欧几里德)
- sicily--1306. Sorting Algorithm
- 在iOS4中使用代码块
- C++中 string 的使用
- [bfs] poj 1753 Flip Game# bfs + 位存储
- 计算机网络层(3)--------《计算机网络-自顶向下方法》
- ACM水题-数据选取(AC解题报告)
- jndi详解
- Android面试之---谈谈你对Android NDK的理解