UVA-202 Repeating Decimals

题目在这
标签:数组
最近做了一系列的字符串的题目,这个题目我是看了题解做的,自己做的时候也没有思路,还以为仍然是字符串的题,却没想到怎么表示。
反思了一下,发现自己卡在了除法取余的哪一步,所以在做这道题的时候一定要时刻保持一个“竖式除法的思维”——除完之后,余数会进行乘10,再进行除法,然后用到的是普通数组。
那么,数组里保存的是什么?
商?——不完全是,一步除法就可以得出商的整数部分,所以数组里存储小数部分即可。
但是,小数到底有多少循环节的个数不知道,所以用普通的数组是比较困难的,就采用了C++STL里的vector存储小数部分。
还剩最后一个,如何判断开始循环了?
脑子里突然冒出一个傻瓜念头,在遍历一遍撒?hhh,被自己的粗暴傻到了
再次回到竖式除法,什么时候是循环的开始呢?对,就是余数出现过的时候就开始了新的循环周期。
我们其实可以用一个数组来记录出现过的余数,一旦碰到了以前出现过的余数,就开始输出,最后break。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <ctime>
#include <ctype.h>
#define ll long long
#define local
#define inf 0x3f3f3f3f
using namespace std;
const int N = 30050;
const int mod = 1e9 + 7;
int n,m;
char x[]= {" = number of digits in repeating cycle"};
int re[N];
vector <int> xiao;//不知道循环周期是多少,不好开固定数组
int main()
{
#ifdef local
    freopen("input.txt","r",stdin);
#endif
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        xiao.clear();
        memset(re,-1,sizeof(re));
        int a=n/m;
        int b=n%m;
        printf("%d/%d = %d.",n,m,a);
        re[b]=0;//把第一个余数所在的位置作为素组首位置
        b*=10;//后面要继续进行除法运算
        int cnt=0;
        while(1)
        {
            int t=b/m;//小数部分的商
            xiao.push_back(t);
            b%=m;//继续取余
            cnt++;
            if(re[b]!=-1)//回到了一个余数已经出现的位置,说明开始循环
            {
                int p=0;//记录小数部分的个数
                for(int i=0; i<re[b]; p++,i++)
                    printf("%d",xiao[i]);
                printf("(");
                for(int i=re[b]; p<50&&i<cnt; p++,i++) //从循环的地方开始
                    printf("%d",xiao[i]);
                if(p==50)//不能超过50
                    printf("...");
                printf(")\n");
                printf("   %d%s\n\n",cnt-re[b],x);
                break;
            }
            re[b]=cnt;
            b*=10;
        }

    }
    return 0;
}

参考自:
https://vjudge.net/status/#un=Wayward&OJId=UVA&probNum=202&res=0&language=&onlyFollowee=false

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值