当前位置: 首页 > news >正文

2024年9月电子学会等级考试五级第三题——整数分解

题目

3、整数分解
正整数 N 的 K-P 分解是指将 N 写成 K 个正整数的 P 次方的和。本题就请你对任意给定的正整数 N、K、P,写出 N 的 K-P 分解。
时间限制:8000
内存限制:262144
输入
输入在一行给出 3 个正整数 N (≤ 400)、K (≤ N)、P (1 < P ≤ 7),以空格分隔。
输出
如果存在解,则按下列格式输出: N = n[1]^P + … n[K]^P 其中 n[i] (i = 1, …, K) 是第 i 个分解因子。所有的分解因子要按非增顺序输出。 注意:解可能是不唯一的。例如 169 的 5-2 分解就存在 9 个解,如 12^2 + 4^2 + 2^2 + 2^2 + 1^2 或 11^2 + 6^2 + 2^2 + 2^2 + 2^2 等等。你必须输出分解因子和最大的那个解。如果还不唯一,则输出具有最大的分解因子序列的解 —— 我们称序列 { a1, a2, … , aK } 比序列 { b1, b2, … , bK } 大,如果存在 1 ≤ L ≤ K 使得 ai=bi 对于 i < L 成立,并且有 aL > bL。 如果解不存在,则输出 Impossible
样例输入
样例#1:
169 5 2

样例#2:
169 167 3
样例输出
样例#1:
169 = 6^2 + 6^2 + 6^2 + 6^2 + 5^2

样例#2:
Impossible

代码

#include <bits/stdc++.h>
#include <windows.h>
using namespace std;
struct node{int num,//因数 x;//底数bool operator<(const node &b)const{return num>b.num;}//重载<比较运算符,定义比较规则。这里是反序,大了才小(sort默认<升序,这里改成降序) //第一个const是常量引用,第二个是不修改该成员变量 
};
int n,k,p,ans=0;
vector<node> ans_v,v;//最终因数和深搜时因数 
void view(string s,const vector<node> &v){cout<<s<<endl;for(auto x=v.begin();x!=v.end();x++)if(x==v.begin())cout<<n<<":"<<x->x<<"^"<<p;else cout<<"+"<<x->x<<"^"<<p;cout<<endl;//Sleep(3000);
}
//bool go(剩因数和,剩几个数,上个因数){
void go(int he,int left,int num){if(he<0||left<0||he>0&&left==0||he==0&&left){//剪枝 cout<<endl;return;}cout<<"出发状态:"<<he<<"\t"<<left<<endl;if(he==0&&left==0){//到达目标状态,凑够了 view("again",v);int sum=0;sort(v.begin(),v.end());for(auto i=v.begin();i!=v.end();i++)sum+=i->x;//因数底数和 cout<<sum<<"\t"<<ans<<endl;if(sum<ans)return;//因数底数和小了 else if(sum==ans){//一样则用字典序高 bool k=1;for(vector<node>::iterator i=v.begin(),j=ans_v.begin();i!=v.end();i++,j++)if(i->x>j->x)break;else if(i->x<j->x){k=0;break;}if(k)ans_v=v;else return;}else{ans_v=v,ans=sum;view("ok",v);}}for(int x=he;x>0;x--){//遍历因数 int d=pow(x,1.0/p); //开方计算求底数 if(pow(d,p)!=x)continue;//不能开方 if(x>num)continue;//剪枝重复情况,10+5和5+10是同种情况,这里只要降序 if(x*left<he)break;//剪枝凑不够情况,剩的全是最大因数都不够凑目标数 cout<<"分出"<<x<<";";v2.push_back({x,d});go(he-x,left-1,x);//继续对剩余数拆解因数 v2.pop_back();//回溯 }
}
int main(){freopen("data.cpp","r",stdin);cin>>n>>k>>p;go(n,k,n);if(ans==0)cout<<"imposibel";else {for(auto i=ans_v.begin();i!=ans_v.end();i++){if(i==ans_v.begin())cout<<n<<"="<<i->x<<"^"<<p;else cout<<"+"<<i->x<<"^"<<p;}}return 0;
}

分析

  • 是k个数的和,
  • 而且每个数都是p次幂
  • 各因子的和最大
  • 和相同,选择字典序最大
  • 指数运算(乘方运算) 2^4=16 底数2, 指数4, 幂是16
  • 开放运算 pow(16,-1.0/4) 底数16,指数1.0/4 根是2
  • 剪枝条件:如果当前因数乘以剩余个数少于剩余总和,则跳过该值。

结果

会有多组解,
留下因数底数和最大的
一样大的,留下字典序高的
在这里插入图片描述

小结

分层解决问题
先解决因数和的事情
再解决开方的问题
然后是因数和
后是字典序
该问题状态都,用BFS需要空间大

相关文章:

  • 【蓝桥杯省赛真题49】python偶数 第十五届蓝桥杯青少组Python编程省赛真题解析
  • zynq嵌入式linux启动默认设置
  • 钉钉数据与金蝶云星空的无缝集成解决方案
  • 嵌入式开发学习日志(数据结构--双链表)Day21
  • C++ QT图片查看器
  • 掘金中亚货代蓝海,易境通货代系统解锁数字化制胜密码!
  • Python实战案例:打造趣味猜拳小游戏
  • 山东大学计算机图形学期末复习整理5——CG10上
  • 司法系统之外的第三方平台未经许可披露企业涉诉信息是否构成侵权
  • CodeBuddy编程新范式
  • 动态规划-状态压缩DP
  • Java并发编程:synchronized机制
  • vue2 根据不同路由url设置不同的网页背景颜色
  • android display 笔记(十四)VAU 和GSP 分别代表什么
  • 谷歌量子计算机:开启计算新纪元
  • 鸿蒙OSUniApp 实现的表单验证与提交功能#三方框架 #Uniapp
  • 2021-10-25 C++三的倍数含五
  • 【图片识别工具】批量单据识别批量重命名,批量OCR识别图片文字并重命名,批量改名工具的使用步骤和注意事项
  • OpenCv高阶(4.0)——案例:海报的透视变换
  • 无需付费,安装就能使用!
  • 上海比常年平均时间提前12天入夏,明天最高气温可达33℃
  • 人形机器人灵犀X2掌握新技能:有了“内心戏”,还会拳脚功夫
  • 蒋圣龙突遭伤病出战世预赛存疑,国足生死战后防线严重减员
  • 张广智︱“编年事辑”:打开学人心路历程的窗户
  • 基金经理调仓引发大金融板块拉升?公募新规落地究竟利好哪些板块
  • 陕西省安康市汉阴县县长陈永乐已任汉阴县委书记