分数转小数,循环小数的循环节要放在括号内
方法是模拟触发操作,然后记录下余数,每次生成的余数检查以前是否出现过,出现过说明出现了循环节,则找到循环节开始的地方。
这题一点都不好写,我反正是打了好多补丁的感觉。
/*
ID: modengd1
PROG: fracdec
LANG: C++
*/
#include <iostream>
#include <stdio.h>
#include <memory.h>
#include <vector>
#include <math.h>
using namespace std;
void output(int ans1,vector<int> ans2,int cystart,bool iscycle)
{
int lenofNotfloat =0;
for(int i=0;pow(10,i-1)<=ans1;i++)
lenofNotfloat=i;
cout<<ans1<<'.';
if(ans1==0)
lenofNotfloat++;
lenofNotfloat++;
if(ans2.size()==0)
cout<<0;
int i;
for( i=0;i<cystart;i++)
{
cout<<ans2[i];
if((i+lenofNotfloat)%76==75)
cout<<endl;
}
if(iscycle)
{
cout<<'(';
lenofNotfloat++;
if((i+lenofNotfloat)%76==75)
cout<<endl;
}
for(;i<ans2.size();i++)
{
cout<<ans2[i];
if((i+lenofNotfloat)%76==75)
cout<<endl;
}
if(iscycle)
{
cout<<')';
lenofNotfloat++;
if((i+lenofNotfloat)%76==75)
cout<<endl;
}
cout<<endl;
}
int main()
{
freopen("fracdec.in","r",stdin);
freopen("fracdec.out","w",stdout);
bool vis[1000000];
memset(vis,false,sizeof(vis));
vector<int> mods;//记录每次除得的余数
int N,D;
int ans1;//整数部分
vector<int> ans2;//小数部分
bool iscycle=false;;//是否循环小数
int cystart=-1;//循环节开始的第几位小数
scanf("%d%d",&N,&D);
ans1=N/D;//求出整数部分
N%=D;//得到第一个余数,这个余数若不等于0,则从它后面的计算开始产生小数
N*=10;//给余数乘10,从此这个数产生第一位小数
mods.push_back(N);
vis[N]=true;
while(N!=0&&!iscycle)
{
if(N<D)//新的被除数小于除数,给被除数乘10,给商末尾写上0
{
ans2.push_back(0);
N*=10;
}
else
{
ans2.push_back(N/D);//写入新求得的商
N=N%D;//产生新的余数
N*=10;//乘10,生成新的被除数
}
if(vis[N])
for(int i=0;i<mods.size();i++)//检查此余数(其实是余数乘10后得到的新的被除数)是否已经出现过
{
if(mods[i]==N)
{
iscycle=true;
cystart=i;
break;
}
}
if(iscycle)
break;
mods.push_back(N);//记录余数(其实是余数乘10后得到的新的被除数)
vis[N]=true;
}
output(ans1,ans2,cystart,iscycle);
return 0;
}