C++基础编程 最大公约数问题

来源:互联网 发布:数据安全管理规范 编辑:程序博客网 时间:2024/05/16 04:45

题目描述

小赛经常沉迷于网络游戏。有一次,他在玩一个打怪升级的游戏,他的角色的初始能力值为a。在接下来的一段时间内,他将会依次遇见n个怪物,每个怪物的防御力为b1,b2,b3,…bn。如果遇到的怪物防御力bi小于等于小赛的当前能力值c,那么他就能轻松打败怪物,并且使得自己的能力值增加bi;如果bi大于c,那他也能打败怪物,但他的能力值只能增加bi与c的最大公约数。那么问题来了,在一系列的锻炼后,小赛的最终能力值为多少?


#include<iostream>using namespace std;int greatest_common_divisor(int a, int b){if (a<b)swap(a, b);while (b != 0) {int c = a %b;a = b;b = c;}return a;}int main(){long long  n, a;int b[100000];while (cin >> n >> a){int i = 0;while (i < n){cin >> b[i];i++;}i = 0;while (i < n){if (b[i] <= a)a = a + b[i];elsea = a + greatest_common_divisor(a, b[i]);i++;}cout << a<<endl;}}


编程笔记:

本题比较基础,最主要的难点在于求出两个数的最大公约数。

求最大公约数的最简单办法是 使用for循环从1到min(a,b)找到所有的公约数。不过这样的方法无用功太多,时间复杂度太高。在当min(a,b)很大时可能会超时。

所以这里介绍一种辗转相除法。





辗转相除法

例1 。求两个正数8251和6105的最大公因数。

(分析:辗转相除→余数为零→得到结果)

解:8251=6105×1+2146

显然8251与6105的最大公因数也必是2146的因数,同样6105与2146的公因数也必是8251的因数,所以8251与6105的最大公因数也是6105与2146的最大公因数。

6105=2146×2+1813

2146=1813×1+333

1813=333×5+148

333=148×2+37

148=37×4+0

则37为8251与6105的最大公因数。

以上我们求最大公因数的方法就是辗转相除法。也叫欧几里德算法,它是由欧几里德在公元前300年左右首先提出的。

1. 为什么用这个算法能得到两个数的最大公因数?

利用辗转相除法求最大公因数的步骤如下:

第一步:用较大的数m除以较小的数n得到一个商q0和一个余数r0

第二步:若r0=0,则n为m,n的最大公因数;若r0≠0,则用除数n除以余数r0得到一个商q1和一个余数r1

第三步:若r1=0,则r1为m,n的最大公因数;若r1≠0,则用除数r0除以余数r1得到一个商q2和一个余数r2

……

依次计算直至rn=0,此时所得到的rn-1即为所求的最大公因数。



其c++代码实现 就是代码中的函数:

int greatest_common_divisor(int a, int b)



参考资料;

http://blog.csdn.net/thisispan/article/details/7458182

0 0
原创粉丝点击