bzoj2712 -- 类欧几里得算法

与bzoj2187类似,不过是要先将小数转化成四舍五入前的分数

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cmath>
 5 using namespace std;
 6 #define ll long long
 7 struct Node{
 8     ll x,y;
 9     Node(){}
10     Node(ll x,ll y):x(x),y(y){}
11 }a,b,c;
12 int n;
13 ll g,i,j,k,m,x,p;
14 inline ll _Min(ll x,ll y){return x<y?x:y;}
15 inline ll Gcd(ll x,ll y){return y==0?x:Gcd(y,x%y);}
16 inline ll F(ll x,ll y){return (x-1)/y+1;}
17 inline Node Solve(Node a,Node b){
18     g=Gcd(a.x,a.y);a.x/=g;a.y/=g;
19     g=Gcd(b.x,b.y);b.x/=g;b.y/=g;
20     if(a.x==0)return Node(1,b.y/b.x+1);
21     if(a.x/a.y+2<=F(b.x,b.y))return Node(a.x/a.y+1,1);
22     if(a.x/a.y>=1){
23         int x=a.x/a.y;
24         Node c=Solve(Node(a.x%a.y,a.y),Node(b.x-x*b.y,b.y));
25         return Node(c.x+x*c.y,c.y);
26     }
27     if(b.x>b.y)return Node(1,1);
28     Node c=Solve(Node(b.y,b.x),Node(a.y,a.x));
29     return Node(c.y,c.x);
30 }
31 int main()
32 {
33     while(scanf("%d 0.%lld",&n,&x)!=EOF){
34         if(x==0){printf("1\n");continue;}
35         for(p=1;n>=0;n--)p*=10;
36         a=Node(x*10-5,p);b=Node(x*10+5,p);
37         g=Gcd(a.x,a.y);a.x/=g;a.y/=g;
38         g=Gcd(b.x,b.y);b.x/=g;b.y/=g;
39         c=Solve(a,b);
40         printf("%lld\n",_Min(c.y,a.y));
41     }
42     return 0;
43 }
bzoj2721

 

posted @ 2017-03-15 07:42  gjghfd  阅读(305)  评论(0编辑  收藏  举报