原题链接
题目大意
给定一个包含
n
n
n 个元素的整数序列
A
A
A,记作
A
1
…
n
A_{1\dots n}
A1…n。
求另一个包含
n
n
n 个元素的待定整数序列
X
X
X,记
S
=
∑
i
=
1
n
A
i
X
i
S=\sum\limits_{i=1}^nA_iX_i
S=i=1∑nAiXi,使得
S
>
0
S>0
S>0 且
S
S
S 尽可能的小。
输入格式
第一行一个整数
n
n
n,表示序列元素个数。
第二行
n
n
n 个整数,表示序列
A
A
A。
输出格式
一行一个整数,表示 S > 0 S>0 S>0 的前提下 S S S 的最小值。
S a m p l e \mathbf{Sample} Sample I n p u t \mathbf{Input} Input
2
4059 -1782
S a m p l e \mathbf{Sample} Sample O u t p u t \mathbf{Output} Output
99
H
i
n
t
&
E
x
p
l
a
i
n
\mathbf{Hint\&Explain}
Hint&Explain
X
X
X 序列中的元素依此为:11 25
,原因是4059*11+(-1782)*25=99
。
数据范围
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 20 , ∣ A i ∣ ≤ 1 0 5 1≤n≤20,|A_i|\le 10^5 1≤n≤20,∣Ai∣≤105,且 A A A 序列不全为 0 0 0。
解题思路
题目都告诉你了,这题是用裴蜀(贝祖)定理啊。
简介
a , b a,b a,b 互质的充分必要条件是存在整数 x , y x,y x,y 使 a x + b y = 1 ax+by=1 ax+by=1。——摘自百度百科
转化一下,就变成了:
a
x
+
b
y
=
c
,
x
∈
Z
∗
,
y
∈
Z
∗
ax+by=c,x\in\Z^*,y\in\Z^*
ax+by=c,x∈Z∗,y∈Z∗ 成立的充分必要条件是
gcd
(
a
,
b
)
∣
c
\gcd(a,b)|c
gcd(a,b)∣c。其中
Z
∗
\Z^*
Z∗ 表示整数集。
证明:
设
d
=
gcd
(
a
,
b
)
d=\gcd(a,b)
d=gcd(a,b),很显然,有
d
∣
a
,
d
∣
b
d|a,d|b
d∣a,d∣b。
∵
x
∈
Z
∗
,
y
∈
Z
∗
\because x\in\Z^*,y\in\Z^*
∵x∈Z∗,y∈Z∗
∴
d
∣
a
x
,
d
∣
b
y
,
d
∣
(
a
x
+
b
y
)
\therefore d|ax,d|by,d|(ax+by)
∴d∣ax,d∣by,d∣(ax+by)
∴
d
∣
c
\therefore d|c
∴d∣c
∴
gcd
(
a
,
b
)
∣
c
\therefore \gcd(a,b)|c
∴gcd(a,b)∣c
得证。
这里
a
∣
b
a|b
a∣b 的意思是
a
a
a 是
b
b
b 的约数。
那这里的定理是求两个数的时候,那三个数或者更多数的时候呢?
还是一样的,先看3个数,则有:
a
x
+
b
y
+
c
z
=
d
,
x
∈
Z
∗
,
y
∈
Z
∗
,
z
∈
Z
∗
ax+by+cz=d,x\in\Z^*,y\in\Z^*,z\in\Z^*
ax+by+cz=d,x∈Z∗,y∈Z∗,z∈Z∗ 成立的充分必要条件是
gcd
(
a
,
b
,
c
)
∣
d
\gcd(a,b,c)|d
gcd(a,b,c)∣d。
证明我就不讲了,留给读者自行尝试。
最后,回到本题,由于题目中说的是要让 S > 0 S>0 S>0 且 S S S 最小,则答案显然就是 gcd ( A 1 , A 2 , ⋯ , A n ) \gcd(A_1,A_2,\cdots,A_n) gcd(A1,A2,⋯,An)。
注意要处理负数的情况,直接把负数转正就可以了。
上代码
#include<bits/stdc++.h>
using namespace std;
#define fu(i,st,ed) for(int i=st; i<=ed; i++)
#define fd(i,st,ed) for(int i=st; i>=ed; i--)
int gcd(int a,int b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
int n,i,tar;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
/* Code */
cin>>n;
fu(i,1,n)
{
int temp;
cin>>temp;
temp=abs(temp);
if(i==1)
tar=temp;
else
tar=gcd(tar,temp);
}
cout<<tar<<endl;
return 0;
}
完美切题 ∼ \sim ∼