3 0.(4) 0.5 0.32(692307)
4/9 1/2 17/52
讲解:本题涉及到小数与分数的转化问题,具体分成三类情况讨论:
(1)当小数为有限不循环小数时,直接将小数部分提取出来,化成整数,并将其与pow(10,l)进行gcd(a,b)化简即可(l为小数部分的长度);
(2)当小数为无限循环小数且第一位即为循环节时,直接将小数部分提取出来,化成整数,并将其与pow(10,l)-1进行gcd(a,b)化简即可(l为小数部分的长度);
(3)当小数为无限循环小数且第一位不为循环节时,将不是循环节的小数部分提取出来记作a,将循环节提取出来记作b,将 a*pow(10,l2)+b-a 与 (pow(10,l2)-1)*pow(10,l1)进行gcd(a,b)化简即可(l1为小数部分非循环节的长度,l2为小数部分循环节的长度);
*证明过程略,请尽量不要使用pow函数,其参数为double类型,做这种题容易损失精度。
代码如下:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; //全题请不要使用long long,用int就能过,用long long反而过不了,可能是oj中long long使用问题 int gcd(int a,int b) { int r=a%b; while(r) { a=b; b=r; r=a%b; } return b; } void work(char s[]) { int l1=0,l2=0; int L=strlen(s); int a=0,b=0; int i; bool flag=false; for(i=2;i<L;i++) { if(s[i]==‘(‘) { flag=true; break; } l1++; a=a*10+s[i]-‘0‘; } if(flag) for(i+=1;i<L-1;i++) { b=b*10+s[i]-‘0‘; l2++; } int r,t=1; if(!flag) { for(t=1,i=1;i<=l1;i++) t=t*10; r=gcd(a,t); printf("%d/%d\n",a/r,t/r); //printf("%lld %lld\n",a,t); } else { for(t=1,i=1;i<=l2;i++) t*=10; a=a*t+b-a; t--;b=t; for(t=1,i=1;i<=l1;i++) t*=10; b*=t; r=gcd(a,b); printf("%d/%d\n",a/r,b/r); //printf("%lld %lld\n",a,b); } } int main() { int n; scanf("%d",&n); char s[20]; while(n--) { scanf("%s",s); work(s); } return 0; }
原文:http://blog.csdn.net/knight_kaka/article/details/20145505