小数转化为分数
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1717
题意:把小数转化为分数,循环部分用()表示。
void Work(char str[]) { int len = strlen(str); LL a = 0; LL b = 0; int cnt1 = 0; int cnt2 = 0; for(int i=2;i<len;i++) { if(str[i] == '(') break; a = a * 10 + str[i] - '0'; cnt1++; } bool flag = false; for(int i=2;i<len;i++) { if(str[i] == '(' || str[i] == ')') { flag = true; continue; } b = b * 10 + str[i] - '0'; cnt2++; } cnt2 -= cnt1; LL p = b - a; LL q = 0; if(!flag) { p = b; q = 1; cnt2 = 0; } for(int i=0;i<cnt2;i++) q = q * 10 + 9; for(int i=0;i<cnt1;i++) q = q * 10; LL g = gcd(p,q); p /= g; q /= g; cout<<p<<"/"<<q<<endl; }
分数转化为小数
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2522
定理1:有理数a/b (其中0<a<b,(a,b)=1)能表示成纯循环小数的充要条件是(b,10)=1
定理2:有理数a/b, 0<a<b, (a,b)=1,b=(2^α)*(5^β)*b1, (b1,10)=1,b1不等于1,α,β不全为零,则a/b可以表示为纯
循环小数,其不循环的位数为u = max(α,β)
定理1的证明参见 薛利敏的论文 纯循环小数循环节的规律
定理2的证明:通过把b拆成2部分,(10^u)*b1,当然分子a要相应乘以(2^(u-α))*(5^(u-β))即为a'=a*(2^(u-α))*(5^(u-β)),这样对于a'/b1先化成真分数,大于1的部分就是不循环小数部分,小于1的是纯循环小数部分,得证。
void Work(int n) { bool flag = 0; int ans[N],f[N]; memset(ans,0,sizeof(ans)); memset(f,0,sizeof(f)); if(n < 0) { n = -n; flag = 1; } int k = 1; f[k] = 1; int cnt = 0; while(k && n != 1) { k *= 10; ans[cnt++] = k / n; k %= n; if(f[k]) break; f[k] = 1; } if(flag) printf("-"); if(n == 1) puts("1"); else { printf("0."); for(int i=0;i<cnt;i++) printf("%d",ans[i]); puts(""); } }