分数转小数,循环小数的循环节要放在括号内
方法是模拟触发操作,然后记录下余数,每次生成的余数检查以前是否出现过,出现过说明出现了循环节,则找到循环节开始的地方。
这题一点都不好写,我反正是打了好多补丁的感觉。
/* 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; }
时间: 2024-11-15 17:55:08