當前位置:最新電影網 - 電影天堂 - 杭州電力公司ACM3637算法

杭州電力公司ACM3637算法

本題含義:給定壹個開區間(開區間用兩位小數表示,[]中的部分為無限循環),求壹個分數,使分數為

在這個區間內,這個分數的分子和分母之和最小。

想法:

同z 1z 2 . c 1 C2[a 1 a2...安]

1。

壹開始發現1/9 = 0。[1] 1/99 = 0.[01] 1/999 = 0.[001].。。發現了[a1a2a3a4...安]

= a1a2a3a4...安/9999...9 (n),對於無環部分,c1c2可以直接除以100..不知道..這樣,我們就把音程分成了兩部分。

計數a/b c/d

2。

然後,我們讓x和y做a/b

這個公式相當於(暫時不考慮a = 0)d/c

如果不等式的左右值跨越壹個整數,這個整數就是答案ans/1。

否則,d% c/c

這樣這個不等式的值就壹直遞減,最後會使不等式的左右值交叉成壹個整數,這就是答案。

案例ans/1。類似於擴展的歐幾裏得感覺。

最後根據不等式的變換過程還原ans/1。

(中間有壹些小問題,比如__int64,不要越界。)

# include & ltiostream & gt

# include & ltmath.h & gt

使用?命名空間?std

#定義?eps?1e-14

夏爾?s1[20],S2[20];

__int64?gcd(__int64?a,__int64?b)

{

if(b==0)返回?a;

不然呢?回歸?(gcd(b,a % b));

}

__int64?Lcm(__int64?a,__int64?b)

{

回歸?a/gcd(a,b)* b;

}

int?flag1,flag2

作廢?getFenshu(__int64?& ampa,__int64?& ampb,夏爾?*s)

{

__int64?ls,I,sum,temp,j,lcm

__int64?ta,tb,bb;

__int64?a1,b1,a2,B2;

ls = strlen(s);

sum = ta = TB = 0;

for(I = 0;我& ltls;i++)

{

if(s[i]== ' . ')

{

打破;

}

sum = sum * 10+(s[I]-' 0 ');

}

////////////////

for(j = I;j & ltls;j++)

if(s[j]& gt;='0'?& amp& amp?s[j]& lt;='9')

{ flag 1 = sum;打破;}

如果(i==ls)

{

a =總和;

b = 1;

返回;

}

b 1 = 1;

for(i++;我& ltls;i++)

{

if(s[i]=='[')

打破;

b 1 * = 10;

ta = ta * 10+(s[I]-' 0 ');

}

a 1 = ta;

bb = b 1;

temp=gcd(a1,b 1);

a 1/= temp;

b 1/= temp;//a1/b1表示有限分數。

a 1+= b 1 * sum;//a1/b1表示有限分數+整數部分。

if(i==ls){a=a1,b = b 1;?返回;}

a2 = 0;

B2 = 9;

for(i++;我& ltls;i++)

{

如果(s[i]!=']')

a2 = a2 * 10+(s[I]-' 0 ');

不然呢?打破;

B2 = B2 * 10+9;

}

B2 =(B2-9)/10;

temp=gcd(a2,B2);

a2/= temp;

B2/= temp;//a2/b2表示無線電周期的小數部分。

b2 * = bb

/*?temp=gcd(a1,b2)*gcd(a2,b 1);

a 1 =(a 1 * B2+a2 * b 1)/temp;

b 1 = b 1/temp * B2;

*/

lcm=Lcm(b1,B2);

a 1 = LCM/b 1 * a 1+LCM/B2 * a2;

b 1 = LCM;

a = a 1;

b = b 1;//a1/b1表示有限分數。

返回;

}

__int64?Ceil(雙?答

{

回歸?((__int64)?a+1);

}

__int64?地板(雙?答

{

if(fabs(a-(_ _ int 64)a)& lt;eps)回報?(_ _ int 64)a-1;

回歸?((_ _ int 64)a);

}

__int64?x,y,步進;

__int64?yy[1000],xx[1000],temp2

__int64?getAns(__int64?a1,__int64?b1,__int64?a2,__int64?b2)

{

if(a1==0)

{

//?回歸?1;

}

__int64?甲、乙;

a =地板((雙)a2/B2);

b = Ceil((double)a 1/b 1);

如果(a & gt=b)

{

step++;

回歸?b;

}

其他

{

step++;

a = Ceil((double)B2/a2);

if(a1==0)

{

回歸?a;

}

b =地板((double)b 1/a 1);

如果(步驟%2?& amp& amp?a2)

YY[step]= B2/a2;

不然呢?如果(a2)

xx[step]= B2/a2;

如果(b & gt=a)

{

回歸?a;

}

回歸?getAns(b2%a2,a2,b 1-a 1 *(_ _ int 64)(B2/a2),a 1);

}

}

int?主()

{

//?freopen("F.in "," r ",stdin);

__int64?n,I,ii,TT = 0;

__int64?溫度;

__int64?a1,b1,a2,B2;

__int64?甲、乙;

int?ff,ff2

scanf("%I64d ",& ampn);

getchar();

for(ii = 0;ii & ltn;ii++)

{

scanf("%s%s ",& amps1。S2);

getFenshu(a1,b1,s 1);

ff = flag 1;

getFenshu(a2,b2,S2);

ff2 = flag 1;

step = 1;

///////////////////////////

if(ff & lt;ff2)

{

printf("Case?%I64d:?%d/1\n ",++tt,Ceil(ff));繼續;

}

memset(xx,0,sizeof(xx));

memset(yy,0,sizeof(YY));

temp 2 = 1;

temp=getAns(a1,b1,a2,B2);

y=temp,x = temp2

if(a1==0)

{

x = 1;

y = Ceil((double)B2/a2);

}

其他

{

for(I = step-1;我& gt=1;我-)

{

if(yy[i]!=0)

{

x+= YY[I]* y;?

swap(x,y);

}

if(xx[i]!=0)

{

x+= xx[I]* y;

swap(x,y);

}

}

}

temp=gcd(x,y);

x/= temp;

y/= temp;

如果(!(?

((double)x/y & lt;(double)a2/b2?& amp& amp?(double)x/y & gt;(double)a1/b1?)?

||?fabs((double)x/y-(double)a2/B2)& lt;eps?

||?fabs((double)x/y-(double)a 1/b 1)& lt;eps?

))

swap(x,y);

printf("Case?%I64d:?%I64d/%I64d\n ",++tt,x,y);

}

回歸?0;

}