题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1717
题目大意:
思路:
细说这道题可以分成三种,1.只有普通小数不含循环小数,2.只有循环小数,3.混合小数(即两者都有的)。
第一种普通小数:就是将其记录下来然后分子分母化简。
第二种:包含循环小数,将上面的2和3包含在一起了。
//如:0.12(56)
//设置x=0.12(56)
//令a=0.12(56)*100=12.(56)--------(1)
//令b=0.12(56)10000=1256.(56)----(2)
//将(2)-(1)得b-a=x(10000-100)
//得x=b-a/(10000-100)
//或者是单独为循环小数的也是如此
//如:0.(89)
//设置x=0.(89)
//令a=0.(89)*1=0.(89)--------(1)
//令b=0.(89)100=89.(89)----(2)
//将(2)-(1)得b-a=x(100-1)
//得x=b-a/(100-1)
//故可得通式:x=(b-a)/(pow(10,总位数)-pow(10,小数点到括号之间的位数))
ac代码:
#include<stdio.h>
#include<math.h>
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
int main(){
int N;
int i;
int ff;
scanf("%d",&N);
char num[20];
int head;//记录非循环小数的
int circle;//记录循环小数的
int k;//用来记录扫描到小数与'('之间的位数的10次方
int h;//用来记录总的数字位数的10次方
int ans1,ans2;//记录最终结果的
while(N--){
getchar();
ff = 0;
scanf("%s",num);
for(i = 2;num[i]!='\0';i++){
if(num[i] == '('){
ff = 1;
break;
}
}
if(ff == 0){//第一种没有循环小数的情况
ans1 = num[2]-'0';
ans2 = 10;
for(i = 3;num[i]!='\0';i++){
ans1 = (num[i]-'0')+ans1*10;
ans2 *=10;
}
printf("%d/%d\n",ans1/(gcd(ans1,ans2)),ans2/(gcd(ans1,ans2)));
}else{//第二种包含着循环小数的情况
//如:0.12(56)
//设置x=0.12(56)
//令a=0.12(56)*100=12.(56)--------(1)
//令b=0.12(56)*10000=1256.(56)----(2)
//将(2)-(1)得b-a=x*(10000-100)
//得x=b-a/(10000-100)
//或者是单独为循环小数的也是如此
//如:0.(89)
//设置x=0.(89)
//令a=0.(89)*1=0.(89)--------(1)
//令b=0.(89)*100=89.(89)----(2)
//将(2)-(1)得b-a=x*(100-1)
//得x=b-a/(100-1)
//故可得通式:x=(b-a)/(pow(10,总位数)-pow(10,小数点到括号之间的位数))
k = 1;head = 0;
for(i = 2;num[i] != '(';i++){
head = head*10+(num[i]-'0');
k *= 10;
}
h = k;
circle = head;
for(++i;num[i] != ')';i++){
circle = circle * 10 + (num[i]-'0');
h *= 10;
}
ans1 =circle - head;//获得分子
ans2 = h-k;//获得分母
printf("%d/%d\n",ans1/(gcd(ans1,ans2)),ans2/(gcd(ans1,ans2)));
}
}
return 0;
}
来源:CSDN
作者:zhoupingqi2017
链接:https://blog.csdn.net/zhoupingqi2017/article/details/104170993