专栏文章
P13098 构造大师贝贝 题解
P13098题解参与者 3已保存评论 2
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mioyzu8n
- 此快照首次捕获于
- 2025/12/03 03:27 3 个月前
- 此快照最后确认于
- 2025/12/03 03:27 3 个月前
1. 题意解释
给出一个数 ,每次你可以选择 的一个因数 ,并使 且 不可重复,求如何使 成为一个完全平方数。
2. 思路
主播赛时切掉了这道抽象的构造题来讲一下心路历程。
最开始时肯定会想到往最近的完全平方数靠。
然而这样我们会发现,有些数字是无法变成与其最接近的完全平方数的。
例子:。
与 最接近的完全平方数是 ,可你会发现没有办法使 转化为 。
主播本来这时候打算放弃了。
然而数竞的经历让主播想到了分类讨论和整除性。
我们考虑对 分类讨论。
我们让 加上 (这是显然可行的),此时 是一个偶数(显然),再让其加上 ,此时变为 ,变成一个 的倍数。
直接让 加上 (显然可行)变为 ,依然化为 的倍数。
直接让 加上 (显然可行)变为 ,依然化为 的倍数。
此时,对于所有 都已化为 的倍数,我们让 除以 ,转化为 。
不难发现这样的操作可以一直持续直到 已成为一个完全平方数。
至于操作次数,最坏的情况是 ,若 次操作用完可以达到 ,大约是 。
而操作过程中 的最大值显然为 ,不会超过 ,因而此方法可行。
3. 代码实现
没什么特别难的地方,直接上主播的 code:
CPP#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,n,cnt;
vector<int>vec;
void solve(int x,int a){
if(floor(sqrt(x))*floor(sqrt(x))==x){
cout<<cnt<<endl;
for(int i=0;i<vec.size();i++){
cout<<vec[i]<<" ";
}
cout<<endl;
}
else{
if(x%4==1){
cnt+=2;
vec.push_back(a);
vec.push_back(2*a);
solve((x+3)/4,a*4);
}
else if(x%4==2){
cnt++;
vec.push_back(2*a);
solve((x+2)/4,a*4);
}
else if(x%4==3){
cnt++;
vec.push_back(a);
solve((x+1)/4,a*4);
}
else{
solve(x/4,a*4);
}
}
}
signed main(){
cin>>t;
while(t--){
cin>>n;
cnt=0;
vec.clear();
solve(n,1);
}
return 0;
}
相关推荐
评论
共 2 条评论,欢迎与作者交流。
正在加载评论...