前言
感觉挺有意思的,其实并不难,难的是思维。
题目大意
给出一个无限循环小数,求映射到分数上的分子和分母。
思路
看起来很复杂,但是可以分析哪里让我们很头疼。
我们会发现,如果是有限小数,那么就是直接乘以 即可, 为小数位位数。无限小数让我们头疼的部分是在循环那里,所以我们要尝试把它消掉。
我们可以尝试从简单走到难。不妨选一个 ,我们将它设为
然后我们希望可以消掉后面的部分,可以这样做:
好像发现点什么了对吗,让我们看一个稍微复杂一点的, 吧,依然设为 。
这个部分如果把 消掉是不是就转成上面那个了呢?
好像已经发现规律了。但位数有点少,让我们把位数增多吧。
我们已经找到规律了,为了让我们可以写出来,我们把规律总结一下:
设 为不循环的部分的长度, 为循环节的长度, 为小数, 为小数的整数部分。
代码
#include <iostream>
#include <cmath>
using namespace std;
typedef long long ll;
double a;
ll t,n,m;
ll gcd(ll A,ll B){
if(B==0){return A;}
return gcd(B,A%B);
}
int main(){
scanf("%lld",&t);
for (int i = 1; i <=t ; ++i) {
scanf("%lld%lld%lf",&n,&m,&a);
ll k=a;
n=m-n+1;
m-=n;
ll down=(pow(10,m+n)- pow(10,m));
ll up=ll(k*down+ll(pow(10,m+n)*a)-ll(pow(10,m)*a));
ll GCD= gcd(up,down);
printf("%lld %lld\n",up/GCD, down/GCD);
}
return 0;
}
总结
本题的难点在于如何消掉无限循环小数的部分,还有归纳。