蓝桥杯|基本数学运算|高效|常用二进制运算|素数火箭版|n次方火箭版|全排列|(二)
文章目录
- 常用的二进制表格
- 公式
- 求素数|筛选素数
- 规律一:素数定理
- 规律二:
- 我们要找第100002个素数
- Java中的Math.log(double d)
- 题解
- 快速幂运算
- 方法一
- 方法二
- 全排列
常用的二进制表格
奇数的二进制的最低位一定为1 | a & 1 ==1 为奇数 | a & 1 == 0偶数 |
---|---|---|
二进制右移1位等价于除以2,且更快 | a>>1 == a/2 | 1010>>1 == 101(可用于检测每一位是0还是1) |
A^A = 0 | A^0=0 | A ^ A ^ A = A ^ 0 = A |
二进制减法 -1 | 从右往左第一个1变为0,此1右边的0全变为1 | 1011001-1=101100 101100-1=101011 |
利用(x-1)&x可以消掉最低位的1 | 二的整数次方二进制中只含一个1 | 1.不断右移与1相与来判断二进制数1的个数 2.不断左移1来与二进制数相与来判断1的个数 |
与运算:与1相与是”保留“,与0相与是”消除“ | 异或:不同位为1 | 10010 & 01010来保留偶数位 (1010101010 == 0xaaaaa) 10010 &10101来保留奇数位 )(0101010101 == 0x55555) |
公式
求素数|筛选素数
规律一:素数定理
从不大于n的自然数(0-n)随机选一个,它是素数的概率大约是
(n不为0和1)
这里的概率可以理解为频率
逆向思考:
100个中出现素数的概率是1/ln 100; 100 *(1/1n 100) 就代表100个当中素数的个数
规律二:
观察合数9:
它的因数:1 * 9 3 * 3
观察合数15:
它的因数: 除了 1 和 15 外 是 3和5
观察合数20:
它的因数: 1* 20 2 * 10 4*5
发现这些合数总是2的倍数,3的倍数,4的倍速…(当然这是小学的知识…)
2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 | 3 | 5 | 7 | 9 | 11 | 13 | 15 | |||||||
2 | 3 | 5 | 7 | 11 | 13 | |||||||||
2 | 3 | 5 | 7 | 11 | 13 |
所以我们从2开始,在允许的范围内,标记2的倍数,3的倍数…(这些数一定是合数)
我们要找第100002个素数
如果采用传统的一个一个的判断的话时间复杂度就会变成 O(n*logn),这里取100002明显是会超时的
//是否是素数public static boolean isPrime(int x){boolean isPrime = true;if(x ==1 || x%2 == 0 && x != 2 ){isPrime = false;}else{for( int i = 3; i< Math.sqrt(x); i += 2){if( x%i == 0){isPrime = false;break;}}}return isPrime;}
Java中的Math.log(double d)
Java 的Math.log(double a) 函数是以e(2.71828…)为底来计算的,也就是数学中的ln a
如果我们想知道log(2)(1000万)的计算结果,应该怎么做呢?
利用换底公式:
在Java中就是:
Math.log(1000*10000) / Math.log(2)
Math.log的返回值是double
为了方便口算,贴一下log其他公式(其中a^b代表 a的b次幂):
a^(log(a)(b))=b
log(a)(a^b)=b
log(a)(MN)=log(a)(M)+log(a)(N);
log(a)(M÷N)=log(a)(M)-log(a)(N);
log(a)(M^n)=nlog(a)(M)
题解
//where至少是4public static int wherePrime(int where){if(where == 1){return 2;}if (where == 2){return 3;}if (where == 3){ //这三个if保持了一定的鲁棒性,但是where为负数和0还没处理....return 5;}int n = 2;//java中的log 其实是lnwhile(n / Math.log(n) < where){++n;}int [] arr = new int[n];int x = 2;//从二开始 标识它们的整数倍while(x < n){if(arr[x] != 0){//被标记过的直接跳过++x;continue;}int k = 2;//从2倍开始while (x * k < n){arr[x * k] = -1;++k;}++x;}int cnt = 0;int primevalue =0 ;//第where个素数for (int i = 2; i < arr.length; i++) {if(arr[i] == 0){++cnt;}if (cnt == where){primevalue = i;break;}}return primevalue;}
快速幂运算
求一a的n次方,a为整数,n可能很大且不为负数
方法一
public static long ax(long a,long x) throws Exception {if (x < 0){throw new Exception("no no no!!!");}if(a == 0){if (x == 0)return 1;return 0;}if (a!=0 && x==0){return 1;}//前面三if是解决鲁棒性if(x==1){//递归出口return a;}long ex = 1;long temp = a;long ret = 1;//a的11(10)次方先求5次a的2次方while((ex<<1) < x){temp = temp*temp; //a的2次方 翻翻ex = ex << 1;}//再求剩下的1(0)次方//当x为偶数 x -ex == 0//奇数 x - ex == 1ret = ret*ax(a,x-ex);return ret * temp;// 剩下的次方与 中间的结果相乘}
初始指数ex | 指数 x | 循环条件ex<<1 | 进入循环后ex |
---|---|---|---|
1 | 1 | 2 | 不满足条件进不了循环 |
1 | 5 | 2 | 2 |
2 | 5 | 4 | 4 |
4 | 5 | 8 | 退出循环 ex = 4不变 |
1 | 2 | 2 | 不满足条件进不了循环 |
1 | 6 | 2 | 2 |
2 | 6 | 4 | 4 |
4 | 6 | 8 | 退出循环 ex = 4不变 |
while((ex<<1) < x){temp = temp*temp; //a的2次方 翻翻ex = ex << 1;}
方法二
巧用二进制
public static long ax0(long a,long x) throws Exception {if (x < 0){throw new Exception("no no no!!!");}if(a == 0){if (x == 0)return 1;return 0;}if (a!=0 && x==0){return 1;}//前面三if是解决鲁棒性long temp = a;long ret = 1;while (x!=0){//指数x至少为1if ((x & 1) == 1){//最低位是1:通过不断左移来判断ret = ret*temp;//temp就是二进制位对应下的次方}//每移位一次,幂 累乘方一次temp = temp*temp;// a a2 a4 a8//右移x一位x = x >> 1;}return ret;}
测试
long now = System.currentTimeMillis();
System.out.println(ax(2,50));
System.out.println(System.currentTimeMillis()-now + "ms");
now = System.currentTimeMillis();
System.out.println(ax0(2,50));
System.out.println(System.currentTimeMillis()-now + "ms");
全排列
- 将一个数组进行全排列,用递归的方法,其实就是分成两步:
- 每个元素都要做一次首元素
- 从第二个元素到最后一个元素进行全排列
以树形来看->从偷图人那里偷的图:
对1 - (n-1)进行全排列的时候,与 整体做全排列是一样的步骤:
- 每个元素都要做一次首元素
- 从第后一个元素到最后一个元素进行全排列
将arr数组p->q进行全排列
//全排列
public static void perm(int []arr,int p,int q){if(q<p || p<0 || q<0 || q>=arr.length){return;}//递归出口if(p == q){printArray(arr);//没有return 因为这是个有限的for循环 }else {for (int i = p; i <= q; i++) {//外层循环就是全排列数组的每一个数都要开头来一次swap(arr,p,i);//以第i个数开头perm(arr,p+1,q);//以第i个数开头全排列结束,进入递归里面可以发现,递归也会进行本循环,只是i初始化为p+1而已...进入下一层...swap(arr,p,i);//执行到这就表示上一个全排列完成了,恢复位置 这样数组就保持原样未改变}}
}
//交换数组中的两个数public static void swap(int []arr,int i,int j){if(i <0 || j< 0){return;}int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}//打印数组public static void printArray(int []arr){if (arr==null){return;}for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]+"\t");}System.out.println("");}
- 对代码中swap操作的再理解
蓝桥杯|基本数学运算|高效|常用二进制运算|素数火箭版|n次方火箭版|全排列|(二)相关推荐
- 【备战十四届蓝桥杯 | 开篇】如何高效备战蓝桥杯
个人名片:
- 蓝桥杯.直线(数学)
Question: Result: 40257 Solve: 这个题还真不太好想,我也看了好多人的题解~ 这么一整理之后,就是说只要x2-x1, y2-y1, x2y1-x1y2这三个系数出现不同的状 ...
- 2018 蓝桥杯省赛 B 组模拟赛(一)I. 天上的星星(二维前缀和)
题目描述 在一个星光摧残的夜晚,蒜头君一颗一颗的数这天上的星星. 蒜头君给在天上巧妙的画了一个直角坐标系,让所有的星星都分布在第一象.天上有 nn 颗星星,他能知道每一颗星星的坐标和亮度. 现在,蒜头 ...
- 蓝桥杯知识点汇总:基础知识和常用算法
文章目录 JAVA基础语法: 算法竞赛常用的JAVA API: 算法和数据结构 简单算法 简单数据结构 图论 数学 贪心 动态规划 补充 省赛题解 待更: 此系列包含蓝桥杯(软件类)所考察的绝大部分知 ...
- 【蓝桥杯学习笔记】9. 解立方根——二分法+牛顿迭代法
系列文章目录 [蓝桥杯学习笔记]1. 入门基本语法及练习题 [蓝桥杯学习笔记]2. 常用模型----最大公约数和最小公倍数 [蓝桥杯学习笔记]3. 质数判断 [蓝桥杯学习笔记]5. 矩阵乘法 [蓝桥杯 ...
- 【蓝桥杯】Python基础:经济基础决定上层建筑!
前言:今年4月第一次参加蓝桥杯比赛,选择的Python 研究生组赛道.在备赛过程中,发现经常会用到一些编程小技巧,因此笔者整理了一些蓝桥杯Python组编程基础常用的内容,以便日后备用.如果有小伙伴也 ...
- 历届蓝桥杯Scratch编程国赛 初级 中级 青少年编程比赛国赛真题解析【持续更新 已更新至27题】
历届蓝桥杯国赛真题 第十三界.十二届.十一届等历届青少年蓝桥杯Scratch编程比赛国赛真题解析 国赛真题01-河马带球[试看] [蓝桥杯国赛真题01]Scratch河马带球 少儿编程蓝桥杯Scrat ...
- 【算法练习】蓝桥杯训练一:区间k大数查询、最大最小公倍数、k好数
蓝桥杯训练一 一.区间k大数查询(简单)(模拟) 二.最大最小公倍数(中等)(数论) 三.k好数(DP) 一.区间k大数查询(简单)(模拟) 直接模拟就可以,个人觉得题目不严谨,没有说重复元素,也没有 ...
- 蓝桥杯比赛常考算法_备战蓝桥--算法竞赛入门第一章总结
笔者备战蓝桥杯先打算看完<算法竞赛入门经典>第2版,在这里写下第一章的笔记,供自己和大家参考. 鸡兔同笼问题 原题: 已知鸡和兔的总数量为n,总腿数为m.输入n和m,依次输出鸡的数目和兔的 ...
最新文章
- Java黑皮书课后题第5章:5.5(千克与磅之间的互换)编写一个程序,并排显示下面两个表格
- html怎么一段时间把网页背景更换_复盛螺杆压缩机故障怎么维修?
- pandasStudyNoteBook
- 二级计算机vf里的sql,计算机等级考试二级VF考点:SQL语言
- Anaconda下如何创建python2等虚拟环境
- 如何部署和搭建测试log4j 2
- python数据生成可视化_Python数据分析:手把手教你用Pandas生成可视化图表
- 手动编译Spring4.2源码,以及把源码导入myEclipse中
- 文件比较 增量 更新 系统发布 增量更新
- InletexEMC 多人屏幕共享工具
- 阿里云移动热修复Sophix问题汇总
- 小孩子都喜欢的卡通影视角色原来是用maya软件制作出来的
- ★自助饮料售卖机,C语言 编辑题
- 论MongoDB索引选择的重要性
- 高德地图API总结--Marker多点聚合
- json.stringify()详解
- NLP-统计词频之处理停用词
- Vue实现 上传文件到七牛云
- VUE中:printJS使用,附带JsBarcode条码生成器,网页转图片html2canvas,base64上传保存处理,二维码生成库qrcode,二维码/条码扫描识别,domtoimage
- 关于SSD寿命问题的探讨