华为机试题-最小公倍数
今天去华为机试,这是我第一次到华为机试,以前听同学说华为的机试很简单,基本上会个冒泡就可以通过了,所以我也就没怎么准备。结果我只做对了一道。。
华为机试一共三道题,分为简单,中,难。听那些监考官说,简单和中都是挺简单的。先看这两题,会哪道做哪道。
我抽到的题:
1.最小公倍数。
2.给定年月日,与1990/01/01,相差多少天。
3.题目有点长,其实也挺简单的。
看到第一题,第二题。做过ACM的都知道它是水题。。
看到第一题,我就知道可以用先求最大公约数,然后最小公倍数也就求出来了。
可是。。。我忘了最大公约数怎么写了。
于是。。
我用了暴力的方法,不解释了。
int bruteVersion(int a,int b) { vector<int> veci; int min,max; if (a > b) { min = b; max = a; } else { min = a; max = b; } for (int i = 2; i <= min;) { if (min % i == 0 && max % i == 0) { veci.push_back(i); min = min / i; max = max / i; i = 2; } else { ++i; } } int sum = 1; for (vector<int>::iterator iter = veci.begin(); iter != veci.end(); ++iter) { sum *= *iter; } return sum * min * max; }
晚上回到宿舍,我才到网上查了一下辗转相除法。原来真的挺简单的。
辗转相除法
原理:求ab的最大公约数: a=mb+c(带余除法:辗转相除法的步骤) 设n是a,b的最大公约数,则上式可写成na`=mnb`+c 所以,c=n(a`-mb`),所以n也是c的公约数。 同理可证,bc的最大公约数也是a的公约数
求得a,b的最大公约数c之后,就可以通过求a,b与c 的商的乘积 再 与c 的乘积就是a,b的最小公倍数了。
所以得到一下程序。
int simpleVersion(int a, int b) { int tmpa = a, tmpb = b; int c = a % b; while (c != 0) { a = b; b = c; c = a % b; } return b * (tmpa / b) * (tmpb / b); }
简单很多吧。
完整测试代码:
#include <iostream> #include <vector> using namespace std; int simpleVersion(int a, int b); int bruteVersion(int a,int b); int main() { int a,b; cin >> a>>b; cout<<bruteVersion(a,b)<<endl; cout<<simpleVersion(a,b)<<endl; return 0; } int simpleVersion(int a, int b) { int tmpa = a, tmpb = b; int c = a % b; while (c != 0) { a = b; b = c; c = a % b; } return b * (tmpa / b) * (tmpb / b); } int bruteVersion(int a,int b) { vector<int> veci; int min,max; if (a > b) { min = b; max = a; } else { min = a; max = b; } for (int i = 2; i <= min;) { if (min % i == 0 && max % i == 0) { veci.push_back(i); min = min / i; max = max / i; i = 2; } else { ++i; } } int sum = 1; for (vector<int>::iterator iter = veci.begin(); iter != veci.end(); ++iter) { sum *= *iter; } return sum * min * max; }