机试学习笔记07 -- 斐波那契数列、素数判定、素数筛选、二分快速幂、分解素因数、常见数学公式总结、规律神器OEIS、高精度问题
一、斐波那契数列
注意90项大概就会超出int范围
如果项数太大取模的话,可以参考之前的做法。
如果给你一个数列:a(1) = 1, a(n+1) = 1 + 1/a(n)。
那么它的通项公式为:a(n) = fib(n+1) / fib(n)。
#include<bits/stdc++.h>using namespace std;int f[10005] = {0};
int main(){int n;cin >> n;f[0] = 1, f[1] = 1;for(int i = 2; i <= n; ++i){f[i] = f[i-1] + f[i-2];f[i] = f[i] % 2333333;}cout << f[n] << endl;return 0;
}
二、素数判定
注意两点:首先,小于2的数都不是素数。其次,只用判断到根号n即可。
#include<bits/stdc++.h>using namespace std;bool sushu(int n){bool flag = 0;if(n == 1) return 0; //1不是素数 else{for(int i = 2; i <= sqrt(n); ++i){if(n % i == 0) return 0; }return 1;}
}
int main(){int n;cin >> n;for(int i = n; ;++i){if(sushu(i) == 1){cout << i << endl;break;}}return 0;
}
三、素数筛选
用以上方法挨个判断,只能处理10000以内的数。
如下方法是线性复杂度
#include<bits/stdc++.h>using namespace std;//线性素数筛选,prime[0]是素数个数const int maxn = 1000000 + 5;
int prime[maxn];
void getPrime() { memset(prime, 0, sizeof(prime)); for (int i = 2; i <= maxn; i++) { if (!prime[i]) prime[++prime[0]] = i; for (int j = 1; j <= prime[0] && prime[j] * i <= maxn; j++) { prime[prime[j] * i] = 1; if (i % prime[j] == 0) break; } }
} int main(){getPrime();int a, b;while(cin >> a >> b){if(a > b) swap(a, b);int ans = 0;for(int i = 1; i <= prime[0]; ++i){if(prime[i] >= a && prime[i] < b){ans++;}}cout << ans << endl;}return 0;
}
四、分解素因数
前提:素因数的分解是唯一的!
1000000的素数完全够了,如果有两个素因子都大于1000000,那么这个数会大于1000000000000,超出int范围,所以数顶多只有一个超过1000000,那么只要最后当剩下一个大素因子时,把ans++即可。
#include<bits/stdc++.h>using namespace std;//线性素数筛选,prime[0]是素数个数,prime中其他元素是所有素数 const int maxn = 1000000 + 5;
int prime[maxn];
void getPrime() { memset(prime, 0, sizeof(prime)); for (int i = 2; i <= maxn; i++) { if (!prime[i]) prime[++prime[0]] = i; for (int j = 1; j <= prime[0] && prime[j] * i <= maxn; j++) { prime[prime[j] * i] = 1; if (i % prime[j] == 0) break; } }
} int main(){getPrime();int n;while(cin >> n){int ans = 0;for(int i = 1; i <= prime[0]; ++i){while(n % prime[i] == 0){n = n / prime[i];ans++;}if(n == 1) break;}if(n > 1) ans++; //对于大于1000000的素因子,不可能两个都大于,这样会超过范围 cout << ans << endl;} return 0;
}
五、二分快速幂
有一类题目是这样的
求 (x^y) % p
当y很大的时候,我们不能直接用for去一个一个的乘,因为这样的方法复杂度是O(N)的。
可以把y分解,分解成1+2+4+8…这样翻倍。
#include<bits/stdc++.h>using namespace std;typedef long long int ll;ll mod_pow(ll x, ll y, ll mod){ll res = 1;while(y > 0){//只有当该位为1时,去乘此时的x if(y % 2 == 1) res = res * x % mod;x = x * x % mod;y = y / 2;}res = res % mod;return res;
}int main(){ll x, n;cin >> x >> n;cout << mod_pow(x, n, 233333) << endl;return 0;
}
如果x大,y也大,两步走,先大数取模,再二分快速幂。
六、常见数学公式总结
1 错排公式
问题: 十本不同的书放在书架上。现重新摆放,使每本书都不在原来放的位置。有几种摆法?
递推公式为:D(n) = (n - 1) * [D(n - 1) + D(n - 2)]
n=1时,0种;n=2时,1种;n=3时,2种。
2 海伦公式
S = sqrt(p * (p - a) * (p - b) * (p - c))
公式描述:公式中a,b,c分别为三角形三边长,p为半周长,S为三角形的面积。
3 组合数公式
公式描述:
组合数公式是指从n个不同元素中,任取m(m≤n)个元素并成一组,叫做从n个不同元素中取出m个元素的一个组合。
4 卡特兰数
七、规律神器OEIS
http://oeis.org/
八、高精度问题
1 Python解法
Python没有大数
while True:try:a, b = map(int, input().split())c = a + bprint(c)except:break
2 Java解法
import java.math.BigInteger;
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sr=new Scanner(System.in); while (sr.hasNext()) { BigInteger a,b; a=sr.nextBigInteger(); b=sr.nextBigInteger(); System.out.println(a.add(b)); } }
}
3 C、C++解法
第一步:倒转来,倒着存才好存。
#include<bits/stdc++.h>using namespace std;char a[1005];
char b[1005];
char c[1005];int _max(int x, int y){if(x > y) return x;else return y;
}int main(){char s1[1005], s2[1005];while(cin >> s1 >> s2){for(int i = 0; i < 1005; ++i){a[i] = b[i] = c[i] = '\0';}int la = strlen(s1);int lb = strlen(s2);for(int i = 0; i <= la-1; ++i){a[i] = s1[la - i -1];}for(int i = 0; i <= lb-1; ++i){b[i] = s2[lb - i -1];}int carry = 0;int i;int lc = _max(la, lb);for(i = 0; i < lc; ++i){int sum = a[i] - '0' + b[i] - '0' + carry;carry = sum / 10;c[i] = sum % 10 + '0';}if(carry != 0){c[i] = carry + '0';lc++;}for(int j = lc-1; j >= 0; --j){cout << c[j];}cout << endl;}return 0;
}
机试学习笔记07 -- 斐波那契数列、素数判定、素数筛选、二分快速幂、分解素因数、常见数学公式总结、规律神器OEIS、高精度问题相关推荐
- java学习笔记之斐波那契数列
斐波那契数列计算公式为: f(n) = f(n-1)+ f(n-2) 基于此写了一个方法,用于输出一个长度为指定的斐波那契数列(从正数1开始, 即1,1 ,2 ,3 ,5 ....): static ...
- 算法学习笔记五 斐波那契数列
斐波那契数列 一.最基本的 所以,只要知道这个数列的前两项,就可以求出之后所有项了. 核心部分(最简单的递推方法,但是范围是n<=48,否则会超时and溢出): #include <cst ...
- 剑指Offer #07 斐波那契数列(四种解法)| 图文详解
题目来源:牛客网-剑指Offer专题 题目地址:斐波那契数列 题目描述 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0).n<=39 题目解析 ...
- CQUOJ月赛(5月)H题:zzblack与斐波那契数列
H. zzblack与斐波那契数列 Case Time Limit: 3000ms Memory Limit: 65536KB 64-bit integer IO format: %lld ...
- python斐波那契数列前20项_Python初学者笔记:打印出斐波那契数列的前10项
问题:斐波那契数列(意大利语: Successione di Fibonacci),又称黄金分割数列.费波那西数列.费波拿契数.费氏数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.- ...
- linux求斐波那契数列前10项,linux求斐波那契数列的前10项以及总和.
C语言的函数问题求斐波那契前四十个数,斐波那契数列指的是这样一个数列:0.1.1.2.3.5.8.13.21.--在数学 />#include//the nest function used t ...
- JavaScript实现斐波那契数列(Febonacci Array)
文章出自个人博客https://knightyun.github.io/2019/09/02/js-febonacci,转载请申明. 斐波那契(Febonacci)数列是一个神奇的数列,在很多地方都有 ...
- c语言输出斐波那契数列前20项,在c语言中,如何利用数组求斐波那契数列的前20项?...
在c语言中,以vc为例利用数组求斐波那契数列的前20项的具体步骤如下: 1.首先,打开vc: 2.点击文件.新建: 3.选择win32 console application 并在右侧输入工程的名字和 ...
- 从斐波那契数列谈谈代码的性能优化
根据高德纳(Donald Ervin Knuth)的<计算机程序设计艺术>(The Art of Computer Programming), 1150年印度数学家Gopala和金月在研究 ...
- JAVA(4)学习笔记:JVM虚拟机上的栈、大驼峰命名法和小驼峰命名法、实参和形参、重载方法、调用栈、递归练习(汉诺塔+斐波那契数列)、数组的定义、数组的初始化、增强for循环。
接上次的博客:JAVA学习(3)--知识整理以及一些简单程序(猜数字游戏.求各种自幂数.求出一个数字的二进制位中1的个数.获取一个数二进制序列中所有的偶数位和奇数位.求公约数的多种实现方式.输入密码程 ...
最新文章
- 在.NET客户端程序中使用多线程
- C#引用类型转换的几种方式
- VTK:Utilities之CommandSubclass
- C# List.sort排序详解(多权重,升序降序)
- IOS基础之datePicker的使用
- 张善友:自由之精神,中国之队长
- 看完这15张动图,秒懂万有引力与航天难点!
- 针对新手的Java EE7和Maven项目–第1部分–简单的Maven项目结构–父pom
- 没有第三个变量的前提下交换两个变量_JavaScript 交换值的方法,你能想到几种?
- MATLAB学习笔记(五)
- oracle字段去重查询,oracle怎么去重查询
- vue改变标签属性_Vue用v-for给循环标签自身属性添加属性值的方法
- 程序win10_只需3步!教你打造精简win10,去除系统自带程序,运行更快!
- ansible 小试身手
- PostgreSQL 10.1 手册_部分 II. SQL 语言_第 12 章 全文搜索_12.5. 解析器
- 安装Wireshark时提示Npcap失败的解决办法(亲测)
- CentOs7下Zabbix安装教程——准备工作
- css设置背景色透明,字体颜色不透明
- java上传微博图床_php上传图片到微博图床
- Node.js报错:UnhandledPromiseRejectionWarning: Unhandled promise rejection