ACM刷题之HDU————小数化分数2

小数化分数2

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4313    Accepted Submission(s): 1745


Problem Description
Ray 在数学课上听老师说,任何小数都能表示成分数的形式,他开始了化了起来,很快他就完成了,但他又想到一个问题,如何把一个循环小数化成分数呢?
请你写一个程序不但可以将普通小数化成最简分数,也可以把循环小数化成最简分数。
 

Input
第一行是一个整数N,表示有多少组数据。
每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。
 

Output
对每一个对应的小数化成最简分数后输出,占一行。
 

Sample Input
  
  
3 0.(4) 0.5 0.32(692307)
 

Sample Output
  
  
4/9 1/2 17/52

 

一道模拟题,太久没做。。大概做了1个小时吧 终于ac了。这题做的时候要把代码理清楚,不然容易弄混。

记得最后还要化简的!化简用素数表来化简。

其中的0.32(692307) 这种形式,把循环和不循环的部分 分开计算出两个分数,然后进行相加。不循环部分很好理解,同一般的化解。

循环部分的话,要在除等量9的基础上,在后面补上等同于不循环部分长度的0; 

例如0.32(123) 的循环部分化简后应该是 123/99900


下面是ac代码

#include<stdio.h>                          
#include<string.h>                         
#include<stdlib.h>                         
#include<math.h>                           
#include<algorithm>                        
using namespace std;

void huajian(__int64 a,__int64 b,__int64 s[]); 

__int64 s[20000]={0};
__int64 d[20000]={0};                       
int main()                                 
{                                          
	char a[100];    
	__int64 jiu[11]={9,99,999,9999,99999,999999,9999999,99999999,999999999,999999999};                          
	int zu,i,j,len1,w,h,k=0;                          
	__int64 num,zi1,mu1,zi2,mu2,zi,mu,e,q; 
	
	//素数表 s为素数表 
	for(i=1;i<20000;i++)
     d[i]=i+1;
	 for(i=0;i<20000;i++)
     if(d[i]!=0)
       {
         s[k]=d[i];
         for(h=i;h<20000;h++)
           if(d[h]%s[k]==0)
            d[h]=0;
         k++;
       }
	 /s                   
	scanf("%d",&zu);                          
	while(zu--)                               
	{                                         
  		scanf("%s",a);
 		j=0;
 		num=0;                              
  		len1=strlen(a);                        
  		if(a[2]=='(') 		//0.(4) 形式  
		{ 
			for(i=len1-2;i>=3;i--)
			{
				e=(a[i]-'0');
				for(w=0,q=1;w<j;w++)
				{
					q*=10;
				}
				num+=(q*e);
				j++;
			}  
			zi=num;
			mu=jiu[len1-5];
			if(zi%mu==0)
			{
				printf("%I64d\n",zi/mu);
				continue;
			}
			else
			huajian(zi,mu,s);		
		}
		else if(a[len1-1]!=')') 		//0.5 形式 
		{
			for(i=len1-1;i>=2;i--)
			{
				e=(a[i]-'0');
				for(w=0,q=1;w<j;w++)
				{
					q*=10;
				}
				num+=(q*e);
				j++;
			}
			zi=num;
			mu=1+jiu[len1-3];
			if(zi%mu==0)
			{
				printf("%I64d\n",zi/mu);
				continue;
			}
			else
			huajian(zi,mu,s); 	
		}         
		else			//0.32(692307) 形式 
		{
		//先是不循环部分 k为记录不循环部分的数字长度 zi1 mu1是不循环的分数表示 
			for(i=len1-1;a[i]!='(';)
			{
				i--;
				continue;
			}
			i--;
			 for(k=0;i>=2;i--)
			 {
				e=(a[i]-'0');
				for(w=0,q=1;w<j;w++)
				{
					q*=10;
				}
				num+=(q*e);
				j++;
				k++;
			}
			zi1=num;
			mu1=jiu[k-1]+1;
			/下面开始计算循环部分 k是不循环的部分 循环部分的长度用h表示
			num=0;
			j=0;
			h=0;
			for(i=len1-2;i>k+2;i--)
			{
				e=(a[i]-'0');
				for(w=0,q=1;w<j;w++)
				{
					q*=10;
				}
				num+=(q*e);
				j++;
				h++;
			}
			zi2=num;
			mu2=jiu[h-1];
			for(i=0;i<k;i++)
			{
				mu2*=10;
			}
			zi=zi1*mu2+zi2*mu1;
			mu=mu1*mu2;
			huajian(zi,mu,s); 
		}                 		                                         
  	}                                       
} 

void huajian(__int64 a,__int64 b,__int64 s[])
{
	int i,j,k;
	for(i=0;i<2000;)
	{
		if(a%s[i]==0&&b%s[i]==0)
		{
			a/=s[i];
			b/=s[i];
			continue;
		}
		i++;
	} 
	printf("%I64d/%I64d\n",a,b);
}                                         


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值