问题描述
有 N N N 只猴子,为了争夺配偶他们经常打架,第 i i i 只猴子初始战斗力为 a i a_i ai,打架会使猴子战斗力降低。
每一天,战斗力最高的若干只猴子(设战斗力为 X X X)都想争夺配偶,争夺的对象是战斗力最低的猴子(设战斗力为 x x x)。于是,战斗力最高的猴子们就会发生打架事件(即使只有一只猴子),使它们的战斗力全都变成 X − x X - x X−x。
日复一日年复一年,当某一天,所有猴子的战斗力都相等了就不会再打架了。请计算这时猴子的战斗力。
输入格式
第一行一个整数
N
N
N。
接下来
N
N
N 个整数,
a
1
,
a
2
,
⋅
⋅
⋅
,
a
n
a_1,a_2,\cdotp\cdotp\cdotp,a_n
a1,a2,⋅⋅⋅,an。
1
≤
N
≤
1
0
5
1 \le N \le 10^5
1≤N≤105
1
≤
a
i
≤
1
0
9
1 \le a_i \le 10^9
1≤ai≤109
输出格式
一个整数答案。
样例
样例输入1
3
2 6 6
样例输出1
2
样例输入2
15
546 3192 1932 630 2100 4116 3906 3234 1302 1806 3528 3780 252 1008 588
样例输出2
42
样例说明
一开始 2 , 6 , 6 2, 6, 6 2,6,6,一天后 2 , 4 , 4 2,4,4 2,4,4,两天后 2 , 2 , 2 2, 2, 2 2,2,2。
思路
显然,暴力枚举肯定会超时。
考虑变化的过程,用最大的数减去最小的数,相当于辗转向减法求解最大公因数。
所以答案就相当于
g
c
d
(
a
1
,
a
2
,
⋅
⋅
⋅
,
a
n
)
gcd(a_1, a_2, \cdotp\cdotp\cdotp,a_n)
gcd(a1,a2,⋅⋅⋅,an)。
如何求解
g
c
d
gcd
gcd:
定义一个变量
a
n
s
ans
ans,表示
g
c
d
gcd
gcd 的值,
a
n
s
ans
ans 初始为
a
1
a_1
a1。
可以从第2个数起,至第
n
n
n 个数结束,每次求这个数和
a
n
s
ans
ans 个最大公因数。
代码
#include<bits/stdc++.h>
using namespace std;
int n;
int a;
//gcd
int gcd(int x, int y){
if(x > y){
swap(x, y);
}
while(x > 0 && y > 0){
y %= x;
swap(x, y);
}
return x + y;
}
int main(){
int ans;
scanf("%d", &n);
scanf("%d", &ans);
for(int i = 2; i <= n; ++ i){
//边输入边求解
scanf("%d", &a);
ans = gcd(a, ans);
}
printf("%d", ans);
return 0;
}