BlizzardCan 算法之路1
(以上是我托朋友做的头标,hhhhh)
初来乍到的自我介绍
这是BlizzardCan的第一篇博客,我是一名代码届的小白,我从此刻开始从0基础学习算法,并在此做一定的记录与分享,如分享中存在问题,请即时指出,谢谢。(鉴于刚开始做博客,格式的问题请给予我一定的时间进行学习)
4.2.1 Simple division • 试题来源:November 2002 Monthly Contest • 在线测试:UVA 10407
补充
欧几里得算法又称辗转相除法,是指用于计算两个非负整数a,b的最大公约数。应用领域有数学和计算机两个方面。计算公式gcd(a,b) = gcd(b,a mod b)。
欧几里得算法是用来求两个正整数最大公约数的算法。古希腊数学家欧几里得在其著作《The Elements》中最早描述了这种算法,所以被命名为欧几里得算法。
扩展欧几里得算法可用于RSA加密等领域。
假如需要求 1997 和 615 两个正整数的最大公约数,用欧几里得算法,是这样进行的:
1997 / 615 = 3 (余 152)
615 / 152 = 4(余7)
152 / 7 = 21(余5)
7 / 5 = 1 (余2)
5 / 2 = 2 (余1)
2 / 1 = 2 (余0)
至此,最大公约数为1
以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数,所以就得出了 1997 和 615 的最大公约数 1。
•被除数n和除数d之间的整数除运算产生商q和 余数r。q是最大化qd的整数,使得qd≤n, 并且r=n−qd。 •给出一组整数,存在一个整数d,使得每个给 出的整数除以d,所得的余数相同。
• 输入
输入的每行给出一个由空格分隔的非零整数序列。每行的最后一 个数字是0,这个0不属于这一序列。一个序列中至少有2个,至多有1000个数字;一个序列中的数字并不都是相等的。输入的最后一行给出单个0,程序不用处理该行。
• 输出
对于于每一行输入,输出最大的整数,使得输入的每一个整数除以 该数,余数相同。
试题解析 •如果两个不同的数除以一个除数的余数相同, 则这两个不同数的差值一定是除数的倍数。 利用差值枚举除数即可。
•所以,本题的算法如下:先求出原序列的一 阶差分序列,然后求出所有非零元素的GCD。
#include<iostream>
using namespace std;
const int Maxn=1010;
int f[Maxn],n,Ans;
int GCD(int a,int b)
{
if(b==0)
return a;
return GCD(b,a%b);
}
inline int Abs(int x)
{
return x>0?x:-x;
}
int main() {
while (true) {
n = 0;
scanf("%d",&f[++n]);
if (f[n] == 0)break;
while (f[n] != 0)scanf("%d", &f[++n]);
n--;
for (int i = 1; i < n; i++)
f[i] = f[i] + f[i + 1];
Ans = f[1];
for (int i = 2; i < n; i++)
Ans = GCD(f[i] == 0 ? Ans : f[i], Ans);
printf("%d\n", Abs(Ans));
}
return 0;
}