习题3-8 循环小数(Repeating Decimals,ACM/ICPC World Finals 1990,UVa202)

原题链接:https://vjudge.net/problem/UVA-202
分类:数组
备注:思维

题意:

  给两个不超过3000的整数A和B,求A除以B的循环小数位数,按照题目规定将商和循环位数输出。

思路:

  • 首先要想到如果一个余数出现了第二次,那么循环就开始了。
  • 接着思考怎么实现对循环的判断和存取。先手算几个简单的除法,找找感觉。
  • 发现余数都要被记录下来,不要忘了整数部分留下的那个余数。循环小数可能不是从第一位开始。

代码如下:

#include
#include
const int maxn = 3000 + 5;//题目说明了数字不超过3000
int flag[maxn], cnt, a, b, out[maxn], yu[maxn];
int main(void)
{
	while (scanf("%d%d", &a, &b) == 2)
	{
		memset(flag, 0, sizeof(flag));
		printf("%d/%d = %d.", a, b, out[0] = a / b);
		yu[0] = a = a - a / b * b;//记录首个余数
		flag[a] = 1;
		int num = 1, i;
		while (1)
		{
			a *= 10;
			out[num] = a / b;//记录每个商,用于输出
			a -= a / b * b;
			if (flag[a])break;//余数出现过则退出循环
			else flag[a] = 1;
			yu[num++] = a;//记录第一次出现的余数
		}
		for (i = 0; i < num; i++)
			if (yu[i] == a)break;//第几个余数是循环的开始
		cnt = num - i;//循环位数
		for (int j = 1; j <= 50 && j <= num; j++)
		{
			if (j == i + 1)printf("(");//循环要从后一位开始算
			printf("%d", out[j]);
		}
		if (cnt >= 50)printf("...)\n");
		else printf(")\n");
		printf("   %d = number of digits in repeating cycle\n\n", cnt);
	}
	return 0;
}

你可能感兴趣的:(《算法竞赛入门经典(第2版)》)