uva202循环小数
题目
输入两个非零整数n m,输出商和循环节长度。如输入:9 2,输出:4.5(0),循环节长度为1。输入7 3,输出:2.(3),循环节长度为1.
思路
1.n/m=整数部分。
2.n%=m,n*=10,n/m得到第一位小数(注意每一位小数的值是商)
3.步骤2循环,每一次的n%=m得到的余数范围在0~m-1,只要余数开始重复,就说明小数出现循环节。即步骤2只要循环m+1次。
要记录余数和对应小数的值及位置,发现余数重复后,本余数对应的小数不记录,返回到被重复的余数位置,之前的小数自然输出,之后的小数括号内输出。余数位置差为循环节长度。
代码
int main() { int sh[3003], yu[3003], mark[3003];//sh用来记录商,yu记录余数,mark记录余数第一次出现的位置。 int n, m, t; while (cin >> n >> m) { int count = 0; memset(sh, 0, sizeof(sh)); memset(mark, 0, sizeof(mark)); sh[count++] = n / m; //sh[0]为整数部分 n %= m; //n为余数,属于1~m-1 while (n && !mark[n])//余数不为0并且余数没有出现过 { yu[count] = n;//从yu[1]开始保存余数 mark[n] = count; sh[count++] = (10 * n) / m;//从sh[1]开始保存每一位小数 n = 10 * n % m;//n为下一次的余数 }//退出while循环时,n为第一个被重复的余数,count为第二次出现的余数的位置 cout << sh[0] << '.'; for (int i = 1;i < count && i <= 50;i++) { if (n && yu[i] == n)//如果最后余数为0,则循环节值为0长度为1,本条语句不执行 cout << '('; cout << sh[i]; } if (!n) cout << "(0";//余数为0 if (count > 50) cout << "..."; cout << ')' << endl; int ans = count - mark[n]; if (n == 0) ans = 1; cout << "循环节长度为:" << ans << endl; } return 0; }