USACO/Fractions to Decimals

USACO/Fractions to Decimals

Posted by dym on March 12, 2014

本文迁移自老博客,原始链接为 https://seven.blog.ustc.edu.cn/usacofractions-to-decimals/

将分数转换为小数,如果是有限小数,则直接输出结果,若果是循环小数,则找到循环节并用括号括起来表示后面的循环部分。规则如下: 1/3 = 0.(3) 22/5 = 4.4 1/7 = 0.(142857) 2/2 = 1.0 3/8 = 0.375 45/56 = 0.803(571428) 解法:模拟除法,找到循环节的关键是出现重复的余数。

#include<iostream>
#include<algorithm>
#include<fstream>
#include<map>
#include<stdio.h>
#include<string.h>
using namespace std;
ofstream fout ("fracdec.out");
ifstream fin ("fracdec.in");

int n,d ,z ,r;
map<int , int> bt;
int ans[1000000];
int s = 1;
bool flag = false;
int pos;
void div()
{
	bt[r] = s;
	while(r / d == 0)
	{
		r *= 10;
		if(bt[r])
		{
			flag = true;
			ans[s++] = 0;
			pos = bt[r];
			return;
		}
		ans[s++] = 0;
	}
	ans[s-1] = r / d;
	r = r % d;
	if(r == 0)
		return;
	if(bt[r])
	{
		flag = true;
		pos = bt[r];
		return;
	}
	else
		div();
}
void output()
{
	fout<<z<<".";
	int count = 0;
	if(z == 0)
		count = 1;
	while(z)
	{
		count++;
		z /= 10;
	}
	count++;
	if(flag)
	{
		for(int i = 1 ; i < s; i++)
		{
			if(i == pos)
			{
				fout<<"(";
				count++;
				if(count > 75)
				{
					fout<<endl;
					count = 0;
				}
			}
			fout<<ans[i];
			count++;
			if(count > 75)
			{
				fout<<endl;
				count = 0;
			}
		}
		fout<<")"<<endl;
	}
	else{	
		for(int i = 1 ; i < s; i++)
			fout<<ans[i];
		fout<<endl;}
}
int main()
{
	fin>>n>>d;
	z = n / d;
	r = n % d;
	if(r != 0)
	{
		div();
		output();
	}
	else
		fout<<z<<"."<<0<<endl;
}