C++题目:循环小数问题

题目描述

数学课上,楠楠学习了一个新的知识。

两数相除,如果得不到整数商,会有两种情况:一种是得到有限小数,另一种是得到无限小数。从小数点后某一位开始依次不断地重复出现前一个或一节数字的十进制无限小数,叫做循环小数,如2.9666…, (在数学中它读作“二点九六,六循环” ), 定义循环小数的缩写法是将第一个循环节以后的数字全部略去,并将第一个循环节首末用括号括起来。

例如:

2.966666… 缩写为 2.9(6)

35.232323…缩写为 35.(23)

楠楠发现,根据循环小数的特征,很快能算出这个循环小数中小数点后第n位的数字,你能吗?

输入

共两行。第一行,包含一个整数n(n≤100000),表示求小数点后的第n位。

第二行,一个字符串,用缩写法表示的一个循环小数。

输出

一行,包含一个整数,表示循环小数中小数点后第n位的数字。

样例输入输出

输入 输出
10 7
352.19(7)

问题分析

将小数点后的非循环小数和循环节存入一个数组里,再根据n的值定位小数点后n位的数字,不过最后定位的时候遇到了点麻烦(我的算法肯定有点问题),导致代码显得冗长。由于博客暂时没有 评论功能,若有更好的想法欢迎给我发邮件:[email protected]

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include<bits/stdc++.h>

const int M = 100010;

using namespace std;

int main()
{
    int n,i,j,x,b[M],k = 0,y = 0;//x为循环节的长度,y为循环内长度
    char a[M];
    cin >> n >> a;
    for(i = 0;a[i] != '.';++i)//定位小数点的位置
    {
        ;
    }
    for(j = 0;a[j] != '(';++j)//定位"("的位置
    {
        ;
    }
    x = j - i -1;
    for(k = 0;k < x;++k,++i)//将循环前的小数写入b
    {
        b[k] = a[i + 1] - '0';
    }
    for(i = j;a[i] != ')';++i)//定位")"的位置
    {
        ;
    }
    y = i - j - 1;
    for(k = x;k < x + y;++k,++j)//将循环节写入小数b
    {
        b[k] = a[j + 1] - '0';
    }
    if(n <= x + y)
    {
        cout << b[n - 1];
    }
    else if((n - x) % y == 0)
    {
        cout << b[x + y - 1];
    }
    else
    {
        cout << b[((n - x) % y) + x - 1];
    }
    return 0;
}