题目链接:
[UVA 202]Repeating Decimals
题意分析:
给出分子、分母。求循环节的长度,并输出循环节,超过50用...代替。
解题思路:
首先是得到小数部分,例如分数 1/3 。整数部分 1/3,小数部分就是(1%3)*10/3每一位的整数部分等于上一位对分母取余乘10再除以分母。不过这里我们写成 (1 - 1/3 * 3) * 10 % 3,防止除数是0的情况。最后是什么时候开始循环,当上一位对分母取余乘10出现重复时,就是出现循环了,因为这之后又和之前一样了(总觉得说了废话的感觉XD)
个人感受:
嘛,怎么找循环节害苦了我TAT。感谢学长。
具体代码如下:#include<iostream>
#include<cctype>
#include<cstdio>
#include<map>
using namespace std;
const int INF = 0x7f7f7f7f, MAXN = 1e4 + 111;
int up[MAXN], deci[MAXN]; //up:分子 deci:整除后结果
int main()
{
int a, b, cycle, s, ed; //这里的s、ed都是要最终记录下来的,以便之后的输出
while (~scanf("%d%d", &a, &b))
{
map<int, bool> mp;
up[0] = a, deci[0] = a / b;
for (ed = 1; ; ++ed)
{
up[ed] = (up[ed - 1] - b * deci[ed - 1]) * 10;
deci[ed] = up[ed] / b;
if (mp[up[ed]])
{
for (s = ed - 1; s; --s)
{
if (up[ed] == up[s])
{
cycle = ed - s;
goto label;
}
}
}
mp[up[ed]] = 1;
}
label:
printf("%d/%d = %d.", a, b, deci[0]);
for (int i = 1; i < s; ++i) printf("%d", deci[i]);
putchar('(');
for (int i = s; i < ed; ++i)
{
if (i > 50)
{
printf("...");
break;
}
printf("%d", deci[i]);
}
printf(")\n");
printf(" %d = number of digits in repeating cycle\n\n", cycle);
}
return 0;
}