蓝桥杯 : 历届试题:小数第n位

问题描述
  我们知道,整数做除法时,有时得到有限小数,有时得到无限循环小数。
  如果我们把有限小数的末尾加上无限多个0,它们就有了统一的形式。

本题的任务是:在上面的约定下,求整数除法小数点后的第n位开始的3位数。
输入格式
  一行三个整数:a b n,用空格分开。a是被除数,b是除数,n是所求的小数后位置(0<a,b,n<1000000000)
输出格式
  一行3位数字,表示:a除以b,小数后第n位开始的3位数字。
样例输入
1 8 1
样例输出
125
样例输入
1 8 3
样例输出
500
样例输入
282866 999000 6
样例输出
914

思路:刚开始得时候我是打算把a/b的值算出来,然后再在这里面找到结果,我当时还觉得这题真 di 简单,测试用例也都过了,就很嗨,可是提交代码后,就很难受,好像只有20分来着。我测试了会儿终于明白,double储存不了这么长的结果,于是我想到了数组,网上确实有人用数组做,不过我闲麻烦。我就找了另一种方法。

#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
int main(void)
{ 
	int a, b, n;   
	double res;//用这个储存结果
	cin >> a >> b >> n;
	res = (double)a / b;  //保证有小数部分
	cout << res;
	while (res > 1)//因为不需要整数部分,所以直接把整数部分剪掉就行了,我原来写的是res--,不过果然还是res-(int)res比较帅
	{
		res -= (int)res;
	}
	while (n-->1)  
	{
		res *= 10;
		res -= (int)res;
	}
	res *= 1000;
	if (res == 0)
	{
		printf("000");
		return 0;
	}
	cout << (int)res;
	return 0;
}

下午的时候我终于搞出来了:
这里其实是模拟除法的过程,因为你得到的商其实是由一步一步的除法算出来的,而每除一次,你都会拿得到的余数来进行下一次除法,所以,最后的答案,其实和每一步的余数有关,所以,这里利用除法来做,不清楚的多用几个数:3/7什么的模拟一下除法过程,就会逐渐清楚了。

#include<bits/stdc++.h>
int main(void)
{
	int a, b, n,yu;//yu是存余数
	scanf_s("%d%d%d", &a, &b, &n);
	yu = a % b;//因为double一次性储存不了那么长的结果,所以我们把结
	//果一次性算出来,而是一步一步的算,这样每次多算出来一位,就可以保证精度
	for (int i = 1; i <= n; i++)
	{
		yu = yu %b*10;//这里我曾考虑过yu=yu*10%b,不过为了跟最后的输出部分搭配,还是这样比较好
		if (yu %b == a % b)//a%b是用来求第一个小数商的余数,
			//而第一次执行的yu%b是求第二个小数商的玉树
		{
			n %= i;//所以这里是i,不是i-1,i就是循环字节的长度
			i = 0;
		}	
	}
	int ans=0 ;
for (int i = 0; i < 3; i++)
	{
		printf("%d", yu / b);
		yu %= b;
		yu *= 10;
	}
    
	return 0;
}

ps:其实这个代码有漏洞的,虽然是满分,但是解决问题不太全面,这里假设的是如果是无限循环小数,那么就一定从小数的第一位开始循环,但实际上有可能是从某一位开始循环(有规律)。可以设置一个数组来解决。。。

猜你喜欢

转载自blog.csdn.net/J_aSON_/article/details/105112931