题目大意:给出小数(包括纯小数以及循环小数),求对应的最简分数。
解题思路:很经典的一道题目,自己模拟了半天也没弄出来,后边看了大神的解题报告才知道如此的巧妙。自己推了一下,然后拍了!自己曾经热爱的数学,那么久没碰过,居然生疏得完全没有灵感了!唉...针对这个题给出几点说明:一是这个题可以很灵活的处理,自己还在那里傻推..这里可以直接将小数分为三部分,第一部分就是头:"0.",第二部分就是不循环的小数部分,记着S1,长度为n,第三部分为循环小数部分记着S2,长度为m。由此我们先将小数乘以10^n,那么就将小数化为X*10^n=S1+Y(0.y1y2...ym)。再将Y部分同理可得:Y*10^m=S2+Y.合并可得:X=(S1*((10^m)-1)+S2)/((10^n)*((10^m)-1))。然后对这个式子分为三种情况求解:两部分长度n和m其中一个为0的情况以及两个都不为0的情况进行求解即可得。最后是一个小细节的应用,接收数据是字符串型的,而后边我们需要对该字符串的部分数据进行截取,可以用头文件为<stdio.h>中的sscanf来进行接收,直接就可以获取你想要的部分,具体应用参见这里解释。其它详见code。
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1717
code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int MAXN = 15;
int n,m,t;
char num[MAXN];
int gcd(int a,int b){
return b==0 ? a : gcd(b,a%b);
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%s",num);
int len = strlen(num);
int i,s1,s2;
for(i=0;i<len;i++)
if(num[i]=='(') break;
n=i-2;
m=len-4-n;
if(n==len-2){
// for(int j=2;j<n+2;j++){
// s1+=num[j]-'0';
// if(j!=n+1) s1*=10;
// }
sscanf(num+2,"%d",&s1);
int f=(int)pow(10,n);
int g=gcd(s1,f);
printf("%d/%d\n",s1/g,f/g);
}
if(m==len-4){
// for(int j=3;j<m+2;j++){
// s2+=num[j]-'0';
// if(j!=m+1) s2*=10;
// }
sscanf(num+3,"%d",&s2);
int f=(int)pow(10,m)-1;
int g=gcd(s2,f);
printf("%d/%d\n",s2/g,f/g);
}
if(m>0 && n>0){
// for(int j=2;j<n+2;j++){
// s1+=num[j]-'0';
// if(j!=n+1) s1*=10;
// }
// for(int j=len-m-1;j<len-1;j++){
// s2+=num[j]-'0';
// if(j!=len-1) s2*=10;
// }
sscanf(num+2,"%d",&s1);
sscanf(num+n+3,"%d",&s2);
int c=s1*((int)pow(10,m)-1)+s2;
int d=(int)pow(10,n)*((int)pow(10,m)-1);
int g=gcd(c,d);
printf("%d/%d\n",c/g,d/g);
}
}
return 0;
}