倒数问题

问题描述


一个正整数的倒数是1除以那个整数。举例来说,37 的倒数是 1/37。有些正整数的倒数是可以用十进制的有限不循环小数表示的,这些正整数包括:

  • 10 的幂;
  • 2 的幂;
  • 2 的幂并跟着数个 0;
  • 5 的幂;
  • 5 的幂并跟着数个 0。

你的任务是求出这样一些整数的倒数,并用十进制表示出来。

输入

输入的第一行是要处理的正整数的个数,后面每一行输入一个正整数。每一个正整数都符合以下条件:

  • 都会从行首开始,
  • 其第一列的数字不为 0,
  • 最多包含 72 个数字。

输出

对于每一个正整数,输出以精确的十进制表示的该数的倒数。每个结果一行。


测试输入关于“测试输入”的帮助 期待的输出关于“期待的输出”的帮助 时间限制关于“时间限制”的帮助 内存限制关于“内存限制”的帮助 额外进程关于“{$a} 个额外进程”的帮助
测试用例 1 以文本方式显示
  1. 4↵
  2. 4↵
  3. 100↵
  4. 6250000↵
  5. 10485760↵
以文本方式显示
  1. 0.25↵
  2. 0.01↵
  3. 0.00000016↵
  4. 0.000000095367431640625↵
1秒 64M 0
题解思路

大致思路:

对于给出的数字,去掉后面的0之后只可能会出现三种情况就是1,2的幂,5的幂。然后对于1,就直接输出1;对于2的幂的倒数可以这样计算,以8为例,1/8=(1/(2*5*2*5*2*5))*5*5*5,意思就是如果不看小数点的话,8的倒数的大小就是5的3次方,什么原因呐,因为我们采用的是10进制,2*5=10,所以上面的方法就是成立。所以对于2的幂的倒数不考虑小数点就是5的相应次方,5的幂的倒数就是2的相应次方。这样就可以把倒数的值计算出来,剩下的事儿就是判断小数的位数。

具体实现:

数字比较大,所以要采用高精度的方法。先去掉数字后面的0,出掉之后可以直接输出相应的0也可以不做操作在最后的时候判断小数到底有多少位,再输出相应个数的0。然后就是判断剩下的数是什么情况,如果是1就直接判断小数位数输出相应个数的0然后输出1;如果剩下的数的最后一位是5那就说明这个数是5的幂,这时就需要用高精度除法计算出这个数是5的多少次方,计算出来之后再计算2的相应次方(这里5的次方数和2的次方数是一样的)就可以得到倒数后面的值,然后计算这个数的倒数的小数位数,输出相应个数的0再将2的相应次方输出即可。剩下的数就是2的幂处理方法和5的幂是一样的。

注意事项:

(1)倒数的小数位数的计算,对于2的幂(后面有0),小数位数就是2的次方数(加上0的个数);对于10的幂,小数位数就是后面0的个数。

(2)高精度除法自己手推一下就出来了,跟乘法相似,只是乘法从各位开始,而除法从最高位开始。


实现代码


<span style="font-family:Microsoft YaHei;font-size:14px;">#include<stdio.h>
#include<string.h>
char yuan[100];
int cheng[1000];
void chu(char *x,int d)
{
	int m,len,yy,zz=0;
	int a[100];
	memset(a,0,sizeof(a));
	len=strlen(x);
	for(m=0;m<len;m++)
	{
		a[m]=x[m]-48;	
	}
	for(m=0;m<len;m++)
	{
		if(a[m]<d)
		{
			a[m+1]+=a[m]*10;
			a[m]=0;
			continue;
		}
		yy=a[m]%d;
		a[m+1]+=yy*10;
		a[m]=a[m]/d;
	}
		for(m=0;m<len;m++)
		{
			if(a[m]!=0)
			{
				zz=m;
				break;
			}
		}
		for(m=0;m<len-zz;m++)
		{
			x[m]=a[m+zz]+48;
			x[len-zz]='\0';
		}
	
}
void chen(int  *x,int y)
{
	int k;
	int length=999;
	while(x[length]==0&&length>0)
	{
		length--;
	}
	length ++;
	for(k=0;k<length;k++)
	{
		x[k]=x[k]*y;
	}
	length++;
	for(k=0;k<length;k++)
	{
		x[k+1]+=x[k]/10;
		x[k]=x[k]%10;
	}
} 

int main()
{
//	int cheng[80];
	int n,i,j,k,length,length1,length2,count,count2,count5,temp,p;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		memset(yuan,-1,sizeof(yuan));
		memset(cheng,0,sizeof(cheng));
		cheng[0]=1;
		count=0;
		count2=0;
		count5=0;
		temp=0;
		length1=0;
		length2=0;
		scanf("%s",yuan);
		length=strlen(yuan);
		if(yuan[0]=='1'&&length==1)
		{
			printf("1\n");
		}
		else
		{
			printf("0.");
			for(j=length-1;yuan[j]=='0';j--)
			{
				count++;
				yuan[j]='\0';
			}
			if(count>0)
			{
			
			
			for(k=1;k<count;k++)
			{
				printf("0");
			}
			if(yuan[j]=='1')
			{
				printf("1\n");
			}
			else if(yuan[j]=='5')
			{
				while(strcmp(yuan,"1")!=0)
				{
					 chu(yuan,5);
					 chen(cheng,2);
					count5++;
				}
				for(p=999;cheng[p]==0;p--)
				{
					length1=p;
				}
				temp=count5-length1+1;
				for(k=1;k<=temp;k++)
				{
					printf("0");
				}
				for(k=length1-1;k>=0;k--)
				{
					printf("%d",cheng[k]);
				}
				printf("\n");
			}
			else
			{
				while(strcmp(yuan,"1")!=0)
				{
					 chu(yuan,2);
					 chen(cheng,5);
					count2++;
				}
				for(p=999;cheng[p]==0;p--)
				{
					length2=p;
				}
				temp=count2-length2+1;
				for(k=1;k<=temp;k++)
				{
					printf("0");
				}
				for(k=length2-1;k>=0;k--)
				{
					printf("%d",cheng[k]);
				}
				printf("\n");
			}
			
			
		    }
		    else
		    {
		    	if(yuan[j]=='1')
			{
				printf("1\n");
			}
			else if(yuan[j]=='5')
			{
				while(strcmp(yuan,"1")!=0)
				{
					 chu(yuan,5);
					 chen(cheng,2);
					count5++;
				}
				for(p=999;cheng[p]==0;p--)
				{
					length1=p;
				}
				temp=count5-length1;
				for(k=1;k<=temp;k++)
				{
					printf("0");
				}
				for(k=length1-1;k>=0;k--)
				{
					printf("%d",cheng[k]);
				}
				printf("\n");
			}
			else
			{
				while(strcmp(yuan,"1")!=0)
				{
					 chu(yuan,2);
					 chen(cheng,5);
					count2++;
				}
				for(p=999;cheng[p]==0;p--)
				{
					length2=p;
				}
				temp=count2-length2;
				for(k=1;k<=temp;k++)
				{
					printf("0");
				}
				for(k=length2-1;k>=0;k--)
				{
					printf("%d",cheng[k]);
				}
				printf("\n");
			}
				
		    	
		    	
		    }
			
		}
	}
	return 0;
}</span>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值