数学问题
1.主要内容
进制转换、最大公约数和最小公倍数、素数筛选、二分求幂、高精度整数
这一部分主要难点在于掌握一些经典的处理方法,还有就是时间复杂度和数据溢出的问题
2.取模运算
(1)计算机中的取模运算a%b,是先计算二者绝对值的模,之后再取和a一样的符号
(2)当计算结果为负值时,与理论结果并不相符。这是需要把负数的结果+b在对b取模,直到结果为正
(3)大数取模防止逸出
(a*b)%m=(a%m*b%m)%m
(a+b)%m=(a%m+b%m)%m
3.数位拆解
要求把输入数据的每位分别进行一些处理,最好的办法使用char数组输入
4.进制转换
(1)库函数方法
这个方法只适用于 已知输入数进制,输入输出都是int可以表示的范围(2^31-1)
使用scanf()输入规定进制的数到int,在使用printf()输出要求转化的机制数
void itoa(int value,char*string,int axis);该函数可以把整数转换成axis(2,8,16)表示的进制字符串,再用“%s”输出即可
int atoi(char *)
View Code(2)手算原理
k进制转10进制:各位依权重k^(n-1)求和
10进制转k进制:先取余(对k),在/=k,不断循环,可得到从低到高的k进制数
View Code
View Code5.最大公约数与最小公倍数
(1)英文分别为 greatest common divisor 和 least common multiple
(2)筛选G常用欧几里得算法:G(a,b)=G(b,a%b) 递归直到第二个形参为0时,返回第一个形参
筛选L常用到公式L=(a*b)/G,这个等式在一些数学题目里也常用到
View Code6.素数
6.1单个素数的判断
(1)1是合数,不是素数
(2)2是素数,1和2需要单独考虑
(3)从i=2开始,到 i^2<=n(这里最好提前计算sqrt(n))结束,如果n可以整除i,那么它是合数;否则是素数
View Code6.2大范围内素数的筛选
(1)一般先利用init()函数,把题目中给定的取值上界内所有的素数都筛选出来
(2)从2开始,如果已经被标记为合数则跳过;如果没有则是素数,记录下来,并把它的倍数全都标记为合数(这里有技巧)
View Code6.3计算素因数
结合6.2的思路,对于N而言:
理论上,大于sqrt(N)的素因数最多有一个
(1)筛选sqrt(N)(最好比这个数大一些)以内的素数,如果是因数,则N/=这个数(此处注意这个数可能是多重因数)
(2)如果筛选完后,如果N不是1,说明存在一个大于sqrt(N)的素因数,也就是N现在的值
7.二分求幂问题
这个问题就是要在a b很大的情况下求a^b
(1)把b化成二进制的形式,如3^31=3^(1111)
(2)把结果写成多个项之积,每项都是前一项的平方,即3^(1111)=3^(1+2+4+8) =(3^1)(3^2) (3^4) (3^8)
(3)这种题通常让求最后结果MOD某个数的值,一定要每步都在ans和a两个地方分别MOD,否则会溢出
View Code结合1.和7.的一个题
View Code8.高精度整数
(1)主要原理使用一个结构体存储位数超出c++限制的数字,无论是+-*/等运算符的重载原理都一样,即
tmp=a1[i](+*-)a2[i](+-)carry;
carry=tmp/10000;
tmp%=10000;
(2)有时间还可以看一下<bits/stdc++.h>这个库
(3)这部分最容易错的是对数组下标的计算以及数组越界问题 必须要特别小心
View Codeposted on 2020-02-08 18:18 mingzhou_liu 阅读(137) 评论(0) 收藏 举报
浙公网安备 33010602011771号