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;
}

很好理解。

AC 记录

赛时 AC 记录

posted @ 2022-01-26 16:42  Shunpower  阅读(45)  评论(0编辑  收藏  举报