算法竞赛入门经典|习题3-8, 循环小数(UVa202)

耗时:1小时22分。

储备知识:

1、循环节

如果无限小数点后,从某一位起向右进行到某一位止的数字循环出现,首位衔接,则称这个小数为循环小数,这段数字为循环节。
例如: 547/7 = 78.(142857)142857。其中, 142857就是循环节。

2、循环节的最大位数

简单理解:
相除就是不断的将因子乘10然后用分子去除,而因子最大不会超过分母,设分母为n,则因子最多为n-1种,
因此循环节最长为n-1。

3、如何计算高精度小数

虽然C语言有%.m的用法去计算小数,但到了位数变多后计算会出现偏差。 因此这里采用动态数组存储小数点后数字的方式。

代码
#include <iostream>
#include <cstdio>
#include <vector> 

using namespace std ;

int main()
{
	int a ;  			//分子 
	int b ; 			//分母
	vector <int> v ;  	//存放结果
	
	cin >> a ;			//输入分子 
	cin >> b ;			//输入分母 
	
	a %= b ;   			//这一步确保a是小于b的,也就是真分数。 
	
	//将计算结果存入 v 
	int num = 0 ;    	//计数,确保存入的个数满足要求
	while(num != (2*b-2)) {
		num++ ;
		if(a < b) {
			a *= 10 ;
		}
		while(a < b) {
			a *= 10 ;
			v.push_back(0) ; 
		}
		v.push_back(a / b) ; 
		a %= b ;
	}

	//判断循环节 
	int j ;
	for(int i = 1 ; i <= (b-1) ; i++) {				//循环节的位数一定不大于b-1。 
		for ( j = i ; j < (2 * b - 2) ; j++) {
			if ( v[j] != v[j % i] ) 
				break ;
		}
		if ( j == (2*b-2) ) {
			cout << i ; 
			return 0 ;
		}
		
	} 
	return 0 ;
 } 

总结:World Finals名不虚传,学到了很多。

发布了27 篇原创文章 · 获赞 16 · 访问量 1961

猜你喜欢

转载自blog.csdn.net/weixin_43899069/article/details/104249122