CF389A Fox and Number Game


洛谷题面

题目大意

\(N(1\leq N\leq 100)\)个数\(x_1,x_2,..,x_n\)

可以根据需要多次执行以下操作:选择两个不同的下标 \(i\)\(j\),保持 \(x_i \gt x_j\) ,然后令 \(x_i \gets x_i - x_j\)

目标是使所有数字的总和尽可能小。

请找到这个最小的总和。

题目分析

\(\boxed{\texttt{性质1:最优解中,所有数都一定会被修改成相等的数。}}\)

证明:

考虑反证法。

假设最优解中并非所有数都相等,那么我们通过相减一定可以得到更优解,这与最优解的定义矛盾,所以得证。


\(\boxed{\texttt{性质2:每次操作后,所有数组的 gcd 保持不变。}}\)

证明:

考虑 \(a_i,a_{j}(a_i>a_{j})\),令 \(a=\gcd(a_i,a_{j})\)

所以 \(a_i=ak,a_j=ap\)\((k,p\) \(\texttt{均为正整数且}\)\(k>p)\)

\(a_i-a_j\)

\(=ak-ap\)

\(=a(k-p)\)

\(\because\) \((k-p)\) 为正整数。

\(\therefore\) 得证。


所以答案为 \(\gcd(a_1,a_2,\cdots,a_{n-1},a_n)\times n\)

代码

//2021/11/17

#define _CRT_SECURE_NO_WARNINGS

#include 

#include 

#include //need "INT_MAX","INT_MIN"

#define enter() putchar(10)

#define debug(c,que) cerr<<#c<<" = "<'9')
		{
		    if(c=='-') flag=true;
		}
		int res=c-'0';
		while((c=getchar())>='0' && c<='9')
		{
		    res=(res<<3)+(res<<1)+c-'0';
		}
		return flag?-res:res;
	}
	inline void print(int x)
	{
		if(x<0)
		{
			putchar('-');x=-x;
		}
		if(x>9)
		{
			print(x/10);
		}
		putchar(x%10+'0');
	}
}

using namespace Newstd;

using namespace std;

int n;

inline int gcd(int a,int b)
{
	if(b==0)
	{
		return a;
	}
	
	return gcd(b,a%b);
}

int main(void)
{
	n=read();
	
	int ans(0);
	
	for(register int i=1;i<=n;i++)
	{
		int x=read();
		
		ans=gcd(ans,x);
	}
	
	printf("%d\n",ans*n);
	
	return 0;
}