UVa202 循环小数
题目描述:给两个整数作除法,找到他们的循环小数部分。
思路:
最重要的就是出现循环节的条件--当做长除法时除得的余数在此前出现过,那么循环就开始了。对这个题而言,需要将每次除得的余数和商都保存下来,再之后找到重复的那个余数后,记录出现的位置,这样可以知道括号的位置。
这个题我是完全对着测试数据来调的代码,没有细致读题,导致花了很多时间在一些细节上,代码也很凌乱。有几个细节的地方,如整个小数部分最多打印50个数字,多的部分用“...)”省略代替,如果循环节的长度刚好是50,括号的位置如果在小数点后,那么能刚好表示下整个循环节,没有“...)”,但对括号在其它位置,就会出现“...)”(具体看54行的条件判断)。
代码:
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 using namespace std; 5 6 int main() 7 { 8 int a, b, y, len, tmp, flag,pos; 9 vector<int> ans; 10 vector<int> ys; 11 // freopen("uva202_in.txt", "r", stdin); 12 // freopen("uva202_out.txt", "w", stdout); 13 while(cin >> a && a != EOF){ 14 flag = 0; 15 cin >> b; 16 if(a / b >= 1) y = a % b; 17 else y = a; 18 ys.push_back(y); 19 while(1){ 20 y *= 10; 21 if(y < b) { 22 tmp = y; 23 } 24 else tmp = y % b; 25 if(tmp == 0){ 26 ans.push_back(y/b); 27 flag = 1; 28 break; 29 } 30 if(find(ys.begin(), ys.end(), tmp) != ys.end()){ 31 pos = find(ys.begin(), ys.end(), tmp) - ys.begin(); 32 ans.push_back(y/b); 33 break; 34 } 35 ys.push_back(tmp); 36 ans.push_back(y/b); 37 y = tmp; 38 } 39 if(flag == 1){ //除法结果为有限小数 40 printf("%d/%d = %d.", a, b, a/b); 41 if(ans.size() == 1 && ans[ans.size()-1] == 0) printf("(0)\n 1 = number of digits in repeating cycle\n\n"); 42 else { 43 for(int i = 0; i < ans.size(); ++i){ 44 printf("%d", ans[i]); 45 } 46 printf("(0)\n 1 = number of digits in repeating cycle\n\n"); 47 } 48 49 }else{ 50 printf("%d/%d = %d.", a, b, a/b); 51 for(int i = 0; i < ans.size(); ++i){ 52 if(i == pos ) printf("("); 53 printf("%d", ans[i]); 54 if(i > 48 && ans.size() > 50 ) { 55 printf("..."); 56 break; 57 } 58 59 } 60 printf(")"); 61 printf("\n %d = number of digits in repeating cycle\n\n", ans.size()-pos); 62 } 63 ys.clear(); 64 ans.clear(); 65 } 66 }