自从学习了C++与STL以后,在解决问题时都时不时主动去思考STL能否解决问题,能否将STL运用到问题中去,越来越多的经验表明,STL的确能大大地节省代码量,如数据结构实验课第一题,相同的解题思想,代码量却节省了80%,且由于STL的模块化,让我们思考问题的时候,更接近于宏观调控,不需要将精力放在自己写的子函数中。同时,为了利用上STL的特性,解题时的思路也得到了拓展,有利于迅速想出可行的解决方案。
今天这个题,也是STL便捷性的集大成者。
题目:
输入整数aaa 和bbb (0≤aaa ≤3000,1≤bbb ≤3000),输出a/b的循环小数表示以及循环节的长度。例如aaa =5,bbb =43 小数表示为0.(116279069767441860465),循环节长度为21。 补充: 如果循环节超过50位,就在第50位后打省略号(三个点,就像“…”)
输入与输出格式
输入输出样例
输入: 76 25
5 43
1 397 输出:
76/25 = 3.04(0)1 = number of digits in repeating cycle5/43 = 0.(116279069767441860465)21 = number of digits in repeating cycle1/397 = 0.(00251889168765743073047858942065491183879093198992...)99 = number of digits in repeating cycle
为了解决这题,我们需要思考:
------------**如何判断循环?**
答:判断循环可以通过模拟竖式计算的方式进行。我们进行竖式计算时可以容易地发现,**当被除数重复时,就是循环节的开始**
------------**采用什么样的数据结构?**
答:由于涉及到高精度的数组,我们采用**STL中的vector容器**用于存储运算结果,使用**STL中的map映射**创建一个数位到数值的映射,利用**map.count()函数**判断结果数值有无在先前计算过作为判断的基础。这样仅需短短10行就可以写出核心find()函数。
-------------
**主要函数应该怎样书写**
答:可以尝试函数的递归调用。
核心find()函数:
#include #include #include using namespace std;vector<int> result; //记录结果map<int, int> dividend; //记录被除数,被除数一旦相同,则为循环节int find(int a, int b){ a *= 10; //模拟竖式运算 if (a == 0) { result.push_back(0); result.push_back(0); return 1; } int c = a / b; result.push_back(c); //把c压入结果 if (dividend.count(a) == 0) dividend[a] = result.size(); //map无a完成a映射 else return result.size() - dividend[a]; int d = a - b * c; return find(d, b);}//返回循环节长度
输出函数与子函数(本题输出过于古怪输出部分可以不看)
void print(int l) //输出与题目有关,该函数不重要{ int key; key = result.size() - l - 1; cout << result[0] << '.'; for (int i = 1; i < key; i++) cout << result[i]; cout << '('; for (int i = key; i < (l > 50 ? 50 : result.size() - 1); i++) cout << result[i]; if (l > 50) cout << "..."; cout << ')' << endl; cout << " " << l << " = number of digits in repeating cycle" << endl << endl; //题目的脑瘫输出格式,忽视它}int main(){ int a, b; while (cin >> a >> b) { result.clear(); dividend.clear(); //清空容器非常重要! int c = a / b, d = a - c * b, longth; result.push_back(c); //压入小数点前的数字直接到第一个位置中 longth = find(d, b); cout << a << '/' << b << " = "; print(longth); } return 0;}
几乎该解法已接近最优解法。