Uva202 循环节

好怀念的题,刚刚进来ACM时老师讲过,不过后来也没有去做,现在又遇上了。
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=138
题目描述:输入整数a和b,输出a/b的循环小数表示以及循环节长度。如a=5,v=43,小数表示为0.(116279069767441860465),循环节长度为21
思路:
(1)模拟前300次运算,将小数每一个部分存储到一个int数组里,再用string流转化为字符串
【注意,不能直接long double a,b,然后a/b,这样的结果是不准确的,计算机由于使用二进制运算,浮点数计算会有误差,对于这道题来说一点误差就意味着错误。】

image.png

(2)找循环节。方法是,先从小数点后第一位开始,由两个开始往后面找字符串(循环节为1的会单独拿出来处理),比如说116279069767441860465,先找到11,然后将他变为两倍(1111),然后在那个500位的小数里面找有无出现这个字符串,然后看紧跟着11的两位(这里是62)是否相等,如果是则找到了循环节。
代码如下:

#include<iostream>
#include<sstream>
#include<string>
#include <iomanip>
using namespace std;
int main(void)
{
    int i,j;
    int a,b;
    int magnification=10;
    int num[300];
    int flag=0;
    string decimal;
    string child_decimal;
    stringstream ss;
    string::size_type idx;
    cin >> a >> b;
    cout << a / b <<'.';
    if (a / b > 0) a = a - (a / b)*b;

    for (i = 1; i <= 300; i++)
    {
        if ((a* magnification) / b == 0)
        {           
            a = a * 10;
            num[i] = 0;
            ss << num[i];
        }
        else
        {
            num[i] = (a* magnification) / b;
            ss << num[i];
            a = a* magnification - ((a*magnification)/b)*b;
        }       
    }
    ss >> decimal;
    for(i=0;;i++)
    {
        for (j = 2; j <= 110; j++)
        {
            child_decimal = decimal.substr(i, j);
            child_decimal += child_decimal;
            idx = decimal.find(child_decimal);//在a中查找b.
            if (idx != string::npos&&decimal.substr(i, j)== decimal.substr(i+j, j))
            {
                cout << decimal.substr(0, i);
                if (child_decimal.substr(0, child_decimal.length() / 4) + child_decimal.substr(0, child_decimal.length() / 4) == child_decimal.substr(0, child_decimal.length() / 2))
                {
                    cout << '(' << child_decimal.substr(0, child_decimal.length() / 4) << ')' << endl;
                    cout << child_decimal.length() / 4 << "=循环节长度" << endl;
                }
                else
                {
                    cout << '(' << child_decimal.substr(0, child_decimal.length() / 2) << ')' << endl;
                    cout << child_decimal.length() / 2 << "=循环节长度" << endl;
                }
                flag = 1;
                break;              
            }
        }
        if (flag == 1) break;
    }
}

原题给出的例子都能测试通过。
运行截图:


image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

但似乎运行效率不高,如果真的提交,那么有可能会超时。
而且会溢出。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容