@因式分解问题@

  • @因式分解问题@

    • @写在前面@
    • @题目描述@
      • @算法1:DFS-原地爆炸瞬间TLE@
      • @算法1.5:DFS优化-然而并没有什么不同@
      • @算法2:部分记忆化 - 只是用来骗部分分@
      • @算法3:正确的DP方法.jpg@
      • @算法4:这才是正解好吧@
    • @正确的代码打开方式@
    • @有些中二的小结 ̄ω ̄=@
    • @END-OF-ALL@

@写在前面@

掐指一算,因式分解问题应该是我思考时长最久的一道题。
但这没关系,我靠着自己坚定的步伐,一步一步的,将这道题斩在了前进的道路上,狠狠地。我并没有借助外部的力量:像是正解博客、或是已做出的同学。
我靠着自己的力量。我坚信:我可以做到。【中二少年!是你!】
尽管我的做法不是最优算法,但是,写写博客让大家知道我的心路历程,也挺好。


@题目描述@

将大于1的自然数N进行因式分解,满足 N=∏mi=1aiN=∏i=1maiN = \prod_{i=1}^{m}a_i 编一个程序,对任意的自然数N,求N的所有形式不同的因式分解方案总数。
例如,N=12,共有8种分解方案,分别是:12 = 12 = 6*2 = 4*3 = 3*4 = 3*2*2 = 2*6 = 2*3*2 = 2*2*3

输入
第1行:1个正整数N(N<=10^9)

输出
第1行:一个整数,表示N的因式分解方案总数

样例输入
12
样例输出
8

@算法1:DFS-原地爆炸瞬间TLE@

第一反应:构造所有方案数。
实现过程非常简单:枚举2~n内n的因子i,将它放在当前一位上,递归枚举n/i。
想想当初的自己也是天真,居然天真地以为这样的算法非常高大上,肯定是个优美的正解……然后用高大上的写法写出来后发现并不是那样的。
而是这样的:
“输入10910910^9”
“等待一秒……”
“等待两秒……”
“等待三秒……”
“栈溢出警告”
“程序关闭”
“内心OS:(╯‵□′)╯︵┻━┻”
DFS果然是很优美地……超时了。

int dfs(int n)
{int k=0;if(n==1) return 1;for(int i=n;i>=2;i--){if(n%i) continue;k+=dfs(n/i);}return k;
}//错误的示范方法

@算法1.5:DFS优化-然而并没有什么不同@

那时的我思考了一刻,突然!脑袋一亮【并不】想到一种优化!枚举因子的时候,可以枚举n/2n/2n/2~n−−√n\sqrt{n}之间的因子iii,然后得到n/i" role="presentation" style="position: relative;">n/in/in/i这个因子。这样,原本寻找因子的时间O(nnn)霎时间就变成了O(n" role="presentation" style="position: relative;">n−−√n\sqrt{n})!!!
我的天啊我真是个天才啊哈哈!
……
……
……
“内心OS:这TM不可能啊为什么它还是TLE(▼ヘ▼#)”

int dfs(int n)
{int k=1;if(n==1) return 1;for(int i=n/2;i>=sqrt(n);i--){if(n%i) continue;if(n/i!=i) k+=dfs(n/i);//不要忘考虑平方根k+=dfs(i);}return k;
}//莫名其妙的无用优化

优化无法让错误的算法AC。

@算法2:部分记忆化 - 只是用来骗部分分@

学到DP时,再次看到了这道题,于是想到记忆化。
然而……然而更尬的问题出现了,10910910^9再怎么开数组也看不下啊!
(╯‵□′)╯︵┻━┻去你的我还以为我想出了正解!
于是聪明的我出了一记十分的机制的损招招式:只开一部分记忆化;另一部分如果超出了某个界限LIM,就用DFS。
啊哈哈我真是骗分达人【然而这不是比赛,部分分没用

const int LIM=1000000;
int f[LIM+5];
int Function(int x)
{if( x <= LIM && f[x] != 0) return f[x];int res=1;for(int i=x/2;i>=sqrt(x);i--){if(x%i) continue;if(x/i!=i) res+=Function(x/i);//不要忘考虑平方根res+=Function(i);}if( x <= LIM ) f[x]=res;return res;
}//骗分专用:部分记忆化

@算法3:正确的DP方法.jpg@

通过观察估算,我们其实发现:状态数并不需要那么多。比方说:对于奇数而言,所有下标为偶数的状态是闲置着的,就会产生白白浪费了很多空间的情况。所以为了保证状态的高效存储——
使用动态数组vector存储,映射表map找到状态是否存在过
哇嘎嘎我真是机智!

map<int,int>m;
vector<long long>f;
long long Function(int x)
{if(x==1) return 0;if( m.count(x) ) return f[m[x]];long long res=1;for(int i=2;i<=sqrt(x);i++)if( x % i == 0) res+=Function(i);for(int i=sqrt(x);i>=2;i--)if( x % i == 0 && i != sqrt(x) ) res+=Function(x/i);m[x]=f.size();f.push_back(res);return res;
}//终于可以AC了

@算法4:这才是正解好吧@

总觉得用vector+map有些别扭,太动态了。
那可不可以在没有DP之前就找到所有合法且可利用的状态呢?
答案是:显然可以【虽然我也没看出来qwq】
从状态转移方程来讲,一个数的转移是由它的因数转移而来的。
它的因数是由它的因数的因数转移而来的,总而言之也是它的因数
所以,我们为何不妨先预处理n的因数,再进行愉快地动规?

@正确的代码打开方式@

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int f[10005],g[10005],len;
void Find_Prime(int x)
{f[len]=1;for(int i=2;i<=sqrt(x);i++)if( x % i == 0) f[++len]=i;for(int i=len;i>=1;i--)if( f[i]*f[i]!=x ) f[++len]=x/f[i];f[++len]=x;
}//寻找n的因数
int Function(int x)//处理的是n的第x个因数
{if(g[x]) return g[x];for(int i=1;i<=x;i++)if( f[x] % f[i] == 0 )g[x]+=Function(lower_bound(f,f+len+1,f[x]/f[i])-f);
//因为因数序列是单调递增的,所以可以使用二分查找return g[x];
}
int main()
{int n;scanf("%d",&n);Find_Prime(n);g[0]=1;printf("%d\n",Function(len));return 0;
}//AC从不是目的,弄懂才是目的

@有些中二的小结 ̄ω ̄=@

如果说,人不遇到点什么困难,是不现实的
人总会遇到形形色色的难处,编程也是,因为我们并非圣贤,并非“生而知之者”
但是,如果遇到一点困难就退缩,遇到一道难题就四处查正解,如果不会自己动脑想问题,不去自己动脑想问题
那样的话,怎么会有自己攻克题目的自豪感?怎么不会充斥“一看题解就懂,然而自己想不出来的尴尬?”
正如标题所言:
你,我,在世界上的任何人
都不适合放弃

@END-OF-ALL@

就是这样,新的一天里,也请多多关照哦(ノω<。)ノ))☆.。~

【CQBZOJ - 1205】因式分解问题相关推荐

  1. python 最快 因式分解_python中怎么对一个数进行因式分解?

    1.Python因式分解代码:import time # 对一个数进行因式分解 def factorization(num): factor = [] while num > 1: for i  ...

  2. 数据库 1205 Error 'Lock wait timeout exceeded; try restarting transaction' on query

    收到报警,mysql的从数据库在同步的过程出现问题,已停止同步. mysql> show slave status\G *************************** 1. row ** ...

  3. java分解因式_用JAVA因式分解 并以9=3×3格式输出

    //输入一个数字,判断是否为素数,如果不是素数,请因式分解packagehomework;importjava.util.Scanner;publicclasshomework7{publicstat ...

  4. 最大公因数、最小公倍数、因式分解

    最大公因数使用辗转相除法来求,最小公倍数则由这个公式来求: GCD * LCM = 两数乘积 解法最大公因数可以使用递回与非递回求解,因式分解基本上就是使用小于输入数的数值当作除数,去除以输入数值,如 ...

  5. HDU-4516 威威猫系列故事——因式分解 多项式分解

    题意:给定一个多项式,对其进行因式分解. 解法:由于多项式每一项系数绝对值不超过1000,由于最后解的形式为(x-a)(x-b)(x-c)(x-d)(x-e)其中a*b*c*d*e一定是最后的常数项系 ...

  6. factor--符号矩阵的因式分解

    [功能简介]求符号表达式的因式分解,此外还能对整数进行素数因子分解. [语法格式] 1.f=factor(n) 对整数n进行素数因子分解,返回包含n的素数因子的行向量. 2.factor(X) 对符号 ...

  7. 蓝桥杯-8-1因式分解(java)

    算法提高 8-1因式分解 时间限制:10.0s 内存限制:256.0MB问题描述设计算法,用户输入合数,程序输出若个素数的乘积.例如,输入6,输出2*3.输入20,输出2*2*5.样例与上面的样例输入 ...

  8. NYOJ 70 阶乘因式分解(二)

    阶乘因式分解(二) 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 给定两个数n,m,其中m是一个素数. 将n(0<=n<=2^31)的阶乘分解质因数,求其中 ...

  9. NYOJ 56 阶乘因式分解(一)

    阶乘因式分解(一) 时间限制:3000 ms  |  内存限制:65535 KB 难度:2 描述 给定两个数m,n,其中m是一个素数. 将n(0<=n<=10000)的阶乘分解质因数,求其 ...

最新文章

  1. android 运动管理,使用 MotionLayout 管理运动和微件动画
  2. python做词云做文本处理_文本挖掘——python词云实现
  3. Android java.lang.UnsatisfiedLinkError
  4. 基于JSON的高级AJAX开发技术
  5. 功能强大的Windows PowerShell
  6. 构造方法重载 java 1615136407
  7. 漫步最优化三十九——Fletcher-Reeves法
  8. java二叉树算法_java构建二叉树算法
  9. mq系列传感器的程序_Cooper Instruments传感器定制解决方案
  10. 二分类数据集_玩转UCI心脏病二分类数据集 领学课笔记
  11. linux mysql远程连接
  12. hp cp1025 linux 驱动,惠普HP LaserJet CP1025 打印机驱动
  13. DHU 数据科学技术与应用【10】 第八次单元测验 时序与语音数据处理 答案
  14. Python中time.sleep(0.001)真的只等待1毫秒吗?
  15. tcpreplay的安装与使用
  16. python中新建标签页的三种方法
  17. Revit二开 VS附加Revit时闪退程序
  18. 使用region注释,将代码块收(折叠)起来
  19. 10款精选的后台管理系统,快来一起颤抖吧!
  20. 十大项目管理知识-相关方识别管理

热门文章

  1. AutoCAD Electrical Essential Training AutoCAD Electrical Essential Training Lynda课程中文字幕
  2. watir学习笔记/ruby
  3. 2022年 微前端技术调研- 图文并茂
  4. 计算机组成原理——微指令格式
  5. iOS底层原理探究 第一探. 事件传递和响应者链
  6. 面试必刷25道面试题(附答案)从容应对互联网大企面试
  7. MySQL入门之目录
  8. CSS通过blur实现高斯模糊
  9. 逻辑回归介绍及statsmodels、sklearn实操
  10. 文件上传:避免重复上传