2018.2.28【 UVa - 202 】解题报告(紫书练习题,循环小数,输出格式)

【题目链接】点击打开链接

【题目大意】

给出一个分数,输出它的循环小数表示。

【解题思路】

判断循环节。两个数组,一个数组yushu[]储存每一位的商,即小数点后面的数字。另一个数组vis[]储存每一次除法计算的商(或者被除数),当vis[]里某个元素访问两遍的时候,循环节出现,即从第一次出现该元素的位置到第二次出现该元素的位置。之后按格式输出即可。

【解题代码】

#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn=3e4+5;
int vis[maxn];
int yushu[maxn];
int up,down;
int main()
{
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
	int kcase=0;
	while(~scanf("%d%d",&up,&down))
	{
		memset(vis,0,sizeof(vis));
		memset(yushu,0,sizeof(yushu));
		//输出相除的形式
		printf("%d/%d = ",up,down); 
		
		//先输出整数部分
		int circle=0;
		int z=up/down;
		yushu[0]=z;
		int yu=up%down*10;
		if(yu==0)//判断是否恰整除 
		{
			printf("%d.(0)\n",z);
			printf("   1 = number of digits in repeating cycle\n");
			continue;
		}
		else//不恰好整除 
		{
			int i=1;
			while(yu)//有限循环则退出 
			{
				if(vis[yu])
				{
					circle=i-vis[yu];//i是当前位置,vis[yu]是上一次出现该被除数的位置。 
					break;
				}
				vis[yu]=i;
				yushu[i]=yu/down;
				i++;
				yu=yu%down*10;
			}
			printf("%d.",yushu[0]);
			if(!yu)
			{
				for(int j=1;j<i;j++)
					printf("%d",yushu[j]);
				printf("(0)\n   1 = number of digits in repeating cycle\n") ;
			}
			else//有循环节 
			{
				int count=0;
				for(int j=1;j<vis[yu];j++)
				{
					printf("%d",yushu[j]);
					count++; 
				}
				printf("(");
				for(int j=vis[yu];j<i;j++)
				{
					if(count>=50)
					{
						printf("...");
						break;
					}
					printf("%d",yushu[j]);
					count++;
				}
				printf(")\n");
				printf("   %d = number of digits in repeating cycle\n\n",circle);
					}
		
	}
	return 0;
} 

【收获与反思】

1.双数组来确定小数的循环节。

2.vis[]数组记录第一次出现某值的位置(同时也可检测是否出现过)。

3.UVa的输出格式比较较真,容易PE,这一题要求每一次输出后有一个空行(而非像其他UVa的题目要求每个答案间有一个空行),细心确认下即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值