题目:
请写出一个程序,接受一个以N/D(0<=N<=65535,0<=D<=65535)的形式输入的分数,其中N为分子,D为分母,输出它的小数形式(运算结果小数点后最多保留100位)。假如它的小数形式存在循环节,要将其用括号括起来。例如:1/3=.33333...表示为.(3),又如41/333=.123123123...表示为.(123)。
一些转化的例子:
1/3=0.(3)
22/5=4.4
1/7=0.(142857)
3/8=0.375
11/59= 0.(1864406779661016949152542372881355932203389830508474576271)
45/47=0.(9574468085106382978723404255319148936170212765)
17/79= 0.(2151898734177)
16/33= 0 .(48)
思路:完全模拟除法运算,可以手算一下来理解,直接用float,double精度是不够的。
#include <iostream> #include <cstdio> using namespace std; int main(){ int res[150], mod[150]; int n, m; cin >> n >> m; res[0] = n / m; //res[0]存小数的整数部分,res[1~]存放小数部分 mod[0] = n % m; //mod 存放除不开的余数部分 int cnt = 1; int i = 0, x = 0, j = 0; while(cnt <= 100 && mod[cnt - 1] != 0){ res[cnt] = (mod[cnt - 1] * 10) / m; //完全模拟除法,可以手动除法来理解,10 / 7 -> 3 / 7 => 3 * 10 / 7 -> mod[cnt] = (mod[cnt - 1] * 10) % m; if(mod[cnt] == 0) break; else{ for(i = 1; i < cnt; i++){ //找循环节 if(mod[i] == mod[cnt]){ //余数相同则后面的运算就相同,就是循环节 break; //循环节从i开始到cnt - 1 } } if(i < cnt){ x = i; //记录循环节开始的位置 break; } } cnt++; } if(x == 0){ //无循环节 cout << res[0] << "."; for(i = 1; i <= cnt; i++) cout << res[i]; } else{ //循环小数 cout << res[0] << "."; for(i = 1; i < x; i++) cout << res[i]; cout << "("; for(i = x; i < cnt; i++) cout << res[i]; cout << ")"; } return 0; }