耗时: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名不虚传,学到了很多。