http://acm.hdu.edu.cn/showproblem.php?pid=6237
这道题目的意思就是有一堆柱子,每个柱子上的石头个数不等,可以任意移动石头到柱子上,找到一个x。使得每一个柱子上的石头的数目都是x的倍数,要求移动最少。
当时我们做重现赛的时候,想的是把所有的柱子上的石子都求和,然后找到最小的质因子,这个质因子就是我们要找的x,我并没有理解为什么这个最小的质因子就是x,然后加上我们用的是素筛法判断质因子,但是数组不能够开那么大,所以总之就是不对。
后来看了一下题解,思路应该是这样的:
既然可以实现这个移动,说明这个x必然是所有柱子上的石头的总和的因子,而且肯定是质因子,但是不一定是哪个质因子是x,但是质因子不会很多,所以都遍历一遍就好,而且找质因子也不要用素筛的数组。
#include
using namespace std;
#include
#include
int num[100005];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int i;
long long sum=0;
for(i=1;i<=n;i++)
{
scanf("%d",&num[i]);
sum+=num[i];
}
vector<int>v1;
vector<int>v2;
for(i=2;i*i<=sum;i++)
{
if(sum%i==0)
{
v1.push_back(i);
while(sum%i==0)
sum=sum/i;
}
}
if(sum!=1)
v1.push_back(sum);
sort(v1.begin(),v1.end());
long long ans=0;
long long minans=1<<62;
int j;
long long yushu=0;
/*for(i=0;i
for(i=0;ifor (j=1;j<=n;j++)
{
int temp;
temp=num[j]%v1[i];
if(temp)
v2.push_back(temp);
yushu+=temp;
}
if(yushu%v1[i]!=0)
continue;
int yushunum=yushu/v1[i];
sort(v2.begin(),v2.end());
int k;
for(k=v2.size()-1;k>=0;k--)
{
ans+=v1[i]-v2[k];
yushunum--;
if(!yushunum)
break;
}
minans=min(minans,ans);
}
printf("%lld\n",ans);
}
return 0;
}
这是一个超时的代码,但是我感觉也没啥不对的啊….
http://blog.csdn.net/qq_24656329/article/details/78519060?locationNum=10&fps=1