题目如上。
这题我是肯定想不出来捏,因为它蕴涵一个可爱的数学知识(bushi。
所有的小数可以表现为两种形式:
1.不循环小数:0.5 则可以转化为5 / 10的分数形式。
2.循环小数:0.333 则可以转化为333 / 999的分数形式。
那这题不就是迎刃而解了吗。
根据pq的位置把不循环小数和循环小数都找出来。
最后得到的就是不循环小数:x/10^(n),循环小数:y/(n个9).其中n是x和y对应的位数。
然后把这两个分数进行约分就好啦。
是不是以为很简单呢,对啊,我这么提交之后得了20分。
为啥呢,因为循环节在后面啊,前面的不循环部分还占了几个0呢!
例如 样例2 2 16 就是1/10 + 6 / (9 * 10);因为6是在第二位,所以得再除以一个10.
说不明白,大家体会一下。
代码如下:
因为数据范围是10位,我怕出现溢出的情况,就都用了long long类型的。
ll gcd(ll a, ll b){
return b == 0 ? a : gcd(b, a % b);
}
int main(){
ll p, q;
cin>>p>>q;
string xs;
cin>>xs;
ll bu = 0; //不循环部分的分子
ll buc = 1; //不循环部分的分母,也就是10^n(n是不循环部分的位数)
ll xh = 0; //循环节部分的分子
ll xhc = 0; //循环节部分的分母,也就是n个9
// ll zw = 1; //占位,循环节未必从小数点后马上开始,
//所以得找出还需要除以10^n,但是其实和buc一样的,直接用buc
//这个占位可以理解为本来是0.03,我们先转化为3/9,但是这不就相当于把0.3扩大了10倍吗,那就分母除以10
for(int i = 1; i < p; i++){
bu *= 10;
bu += xs[i - 1] - '0';
buc = buc * 10;
}
// cout<<bu<<" "<<buc<<endl;
for(int i = p; i <= q; i++){
xh *= 10;
xh += xs[i - 1] - '0';
xhc = xhc * 10 + 9;
}
xhc *= buc;
// cout<<xh<<" "<<xhc<<endl;
ll fenzi = 0;
ll fenmu = 0;
ll g;
if(bu && xh){
fenzi = bu * xhc + buc * xh;
fenmu = xhc * buc;
g = gcd(fenzi, fenmu);
// cout<<fenzi<<" "<<fenmu<<" "<<g<<endl;
}else if(bu){
fenzi = bu;
fenmu = buc;
g = gcd(bu, buc);
// cout<<fenzi<<" "<<fenmu<<" "<<g<<endl;
}else{
fenzi = xh;
fenmu = xhc;
g = gcd(xh, xhc);
// cout<<fenzi<<" "<<fenmu<<" "<<g<<endl;
}
printf("%lld %lld\n", fenzi / g, fenmu / g);
return 0;
}
//1 6
//142857