https://www.luogu.org/problemnew/show/P1530
题解:模拟除法
/*
*@Author: STZG
*@Language: C++
*/
#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
#include<map>
#include<set>
//#define DEBUG
#define RI register int
#define endl "\n"
using namespace std;
typedef long long ll;
//typedef __int128 lll;
const int N=100000+10;
const int M=100000+10;
const int MOD=1e9+7;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
int t,n,m,k,p,l,r,u,v,d,w;
int cnt,flag,temp,sum;
string ans;
int pd[N];
char str;
struct node{};
int main()
{
#ifdef DEBUG
freopen("input.in", "r", stdin);
//freopen("output.out", "w", stdout);
#endif
//ios::sync_with_stdio(false);
//cin.tie(0);
//cout.tie(0);
//scanf("%d",&t);
//while(t--){
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+=')';
//如果结果是一个循环小数,在末尾加个右括号,便于输出
int 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( );
}
//注:我这样处理循环节的开头是为了便于换行,因为左括号也算是字符
//}
#ifdef DEBUG
printf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC);
#endif
//cout << "Hello world!" << endl;
return 0;
}