P7947 [✗✓OI R1] 铝锤制作 题解
思路
考虑先构造数列使得乘积等于 \(n\)。
明显地,直接对 \(n\) 分解质因数即可。由于这样分解出来的数列具有最小和,所以判断仅由 \(n\) 质因数组成的数列和 \(sum\) 与 \(k\) 的大小关系即可。
如果 \(sum=k\),就可以直接输出了。但是 \(sum<k\) 怎么办呢?考虑在不改变乘积的基础上使得 \(sum\) 变到 \(k\)。
显然往数列里添加 \(1\) 可以使得乘积不变,\(sum\) 增大。
所以程序的步骤应该很明确了:先给 \(n\) 分解质因数,然后判断质因数数列的和 \(sum\) 是否 \(>k\),如果是,直接输出 \(-1\);否则往数列里面添加 \(1\) 直到和为 \(k\)。
代码
2.1 分解质因数
void change(int x){//这函数名是乱取的
int k=x;
for(int i=2;i<=k;i++){
while(x%i==0){
p.push_back(i);
sum+=i;
x/=i;
}
}
}
首先先把 \(2\) 从 \(x\) 里面分解完全,接下来 \(x\) 就不再是任何 \(2\) 的倍数的倍数。其它质数同理。
最终 \(n\) 就被分成了质因数加到了 \(p\) 这个vector
里面,\(sum\) 存的是 \(n\) 质因数的和。
2.2 主程序
int main(){
cin>>n>>k;
change(n);
if(sum<k){
for(int i=sum;i!=k;i++){
p.push_back(1);//加1
}
}
if(sum>k){
puts("-1");//判无解
return 0;
}
cout<<p.size()<<endl;
for(int i=0;i<p.size();i++){
cout<<p[i]<<' ';
}
puts("");
return 0;
}
很好理解。