1 条题解
-
1
#include<iostream> #include<fstream> #include<cstdio> #include<algorithm> #include<string> #include<cstring> #include<cmath> #include<vector> using namespace std; int n,d,k,w,sum,len; //w用来记录循环节开始(左括号)的位置,sum为输出使用的计数器 string ans; //答案 int pd[100005]; //pd数组用来记录每个余数出现的位置,判断余数是否重复,便于记录循环节开始(左括号)的位置。根据题目1<=N,D<=100000可得知余数最终不会超过99999 int main() { scanf("%d%d",&n,&d); k=n/d,w=-1; do { ans=char(k%10+'0')+ans; //这种方法要把拆分出来的整数放到前面去,不然会反过来,因为它先拆分个位,再拆分十位,直接加会使个位在前,直接加会使十位在后, k/=10; }while(k>0); //拆分结果的整数部分进ans。由于0也算是整数部分,所以无论如何也要拆分一次,用do{}while(),不然用for() 整数部分为0时就不会拆进去,因为k=0了 ans+='.'; //鉴于结果无论如何至少有一位小数,加个小数点 n=n%d; //被除数取余,开始模拟小数部分的除法运算 do { if(pd[n]!=0) { w=pd[n]; break; } //如果余数有重复,说明这是一个循环小数,上一个n出现的位置便是循环节开始(左括号)的位置 else pd[n]=ans.size(); //否则就记下这个余数变为被除数后对应的商出现的位置,以便未来判断和记录 n*=10; //n变成被除数,末尾加0(N,D一定是正整数,不存在小数可加在末尾) k=n/d; ans+=char(k+'0'); n=n%d; //模拟除法 }while(n!=0); //由于结果如果是正整数的话,末尾也得加0,用do()while{} if(w!=-1) ans+=')'; //如果结果是一个循环小数,在末尾加个右括号,便于输出 len=ans.size(); for(int i=0;i<len;i++) { if(i==w) { putchar('('); i--; w=-1; } //如果这个地方是循环节的开头,在这里输出左括号,并将w改为-1,避免重复输出括号,同时i--,因为这里的ans[i]还没输出 else putchar(ans[i]); sum++; if(sum%76==0) putchar('\n'); //putchar( )可理解为cout<<char( ); } //注:我这样处理循环节的开头是为了便于换行,因为左括号也算是字符 return 0; }
- 1
信息
- ID
- 2012
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 34
- 已通过
- 20
- 上传者