今天去华为机试,这是我第一次到华为机试,以前听同学说华为的机试很简单,基本上会个冒泡就可以通过了,所以我也就没怎么准备。结果我只做对了一道。。
华为机试一共三道题,分为简单,中,难。听那些监考官说,简单和中都是挺简单的。先看这两题,会哪道做哪道。
我抽到的题:
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;
}