题目链接 : http://acm.hdu.edu.cn/showproblem.php?pid=6237
题解 : 对x进行暴力,还有x肯定是质数,肯定能被所有石子数总和sum整除,然而暴力的上界不好确定,不可能定到sum去,就定个最大值100000吧,注意到一种sum是质数的情况,这种的答案就是sum-max(想一想这种也就是x的最大值了),然后就过了。
#include<stdio.h> #include<algorithm> using namespace std; int a[100005],is_prime[100005],b[100005]; bool cmp(int x,int y) { return x<y; } int main() { long long sum,x; int T,MAXN=100005; scanf("%d",&T); //质数筛选 for (int i = 2; i <= MAXN; ++i) { is_prime[i] = 1; } for (int i = 2; i * i <= MAXN; ++i) { if (is_prime[i]) { for (int j = i * i; j <= MAXN; j +=i) { is_prime[j] = 0; } } } while(T--) { long long n,min=100001,y,z,max=0; sum=0; scanf("%lld",&n); for(int i=0;i<n;i++) { scanf("%d",&a[i]); if(a[i]>max) max=a[i]; sum+=a[i]; } min=sum-max; for(int i=2;i<=100000;i++) { if(!is_prime[i]) continue; if(sum%i!=0) continue; long long y=0,s1=0; int j,x; for(j=0;j<n;j++) { if(a[j]%i==0) continue; b[y++]=a[j]%i; } sort(b,b+y,cmp); int l=0,r=y-1; while(l<r) { if(b[l]+b[r]>i) { s1+=i-b[r]; b[l]-=i-b[r]; r--; } else { s1+=b[l]; b[r]+=b[l]; l++; } } if(s1<min) {min=s1;} } printf("%lld ",min); } return 0; }