数学相关题
1.非波那切数列(青蛙跳台阶1个、2个)(矩形覆盖)
跳台阶题目
矩形覆盖题目
----->递归(时间复杂度过高O(2^n)),
------>动态规划:f(n)=f(n-1)+f(n-2); while(n–>2)时;f(n)=f(n-1)+f(n-2)即b=b+a;f(n-1)保存即a=b-a;
注意while中>2是关键;这是由a和b的初始化决定的;
2.青蛙跳台阶,一次跳1个、2个、…n个;
题目
—>f(n)=f(n-1)+f(n-2)+…f(2)+f(1)+f(0); f(0)即一次跳n个;
//初始化f(0)=1; f(1)=1;
while(number-->1)
b=b+a;
a=b;
//或
sum=1;
while(number-->1)
sum*=2;
对于这样的问题,先根据前几项找通式或规律;再写代码;
3.数值的整数次方
题目
----->对次方正负分类讨论
注意是base *= onebase;
int/double为int ; 应为double/double;
4数组中只出现一次的数字:
----->注意&^比==优先级低;所以要在 while((index&xor1)==0)里面加上括号;
考点:& 、^、<<运算;相同两个数异火为0;
while((index&xor1)==0) index<<=1;求最右边1的位置; 即非0时退出;
5.二进制中1的个数
n=n&(n-1); n-1即从右往左数到第一个1开始取反,在与n进行&运算,即将去除原数的最右边的1及后面的;
-1的二进制为32;int的二进制共32位
6.不用加减乘除做加法(^&<<):
题目
---->先异或(使用temp变量保存),在求进位(与与左移),更新结果,只要进位不为空;
do{}while;
求两数之差:依次使用的运算符(&^^|<<):------>1.调用加法(a的负数:Add(~a,1));
2.只要b不为空,先求相同位,两数去除相同位,再与|运算,被减数右移;
异或减
7.判断点p是否在三角形中
内角和等于360度(误差大)或求面积(交叉向量求面积(一定为正值):定义一个结构体,
s=(ab-> * bc->)/2.0=(AB.xBC.y-AB.yBC.x)/2.0)之和,判断时要用&&; ABC、ABP、BCP、ACP;
struct point{
int x;
int y;
point(int i,int j):x(i),y(j){};
};
double area(point A,point B,point C)
{
double x1=A.x-B.x;
double y1=A.y-B.y;
double x2=B.x-C.x;
double y2=B.y-C.y;
return (x1*y2-x2*y1)/2.0;
}
- p点一定在AB边下边,AC边右边,BC边左边;一个Vector3类(构造函数、重载-函数、Dot函数、Cross函数);PointinTriangle函数,SameSide函数();
三角形
8.丑数(只包含2、3、5因子的树)穷举法:
题目
初始化三个指针p1、p2、p3的索引为0;分别指向*2、*3、*5的索引位置;每次将res[pi]*pi中最小的赋值;
- 质数:暴力法j<i(改为sqrt(i)):i%j==0,返回false;
- 质数:筛法:初始化arr(1000,1);如果arr[i]==1:计算j=i;ji<1000;arr[ji]=0;
min(a,b);
9.排序数组和为s且乘积最小的两个数:
题目
—>双指针法:i指向开始,j指向结束;和相同两数相差越远其积越小;
10.游戏:n个孩子,每次数m次,选出的去除,直到剩余最后一个:
题目
1.删除法:.(注意每个变量都要初始化,不一定默认为0)使用vec保存0~n-1的值;每喊m次从vector中erase一个元素;
int LastRemaining_Solution(int n, int m)
{
if(n<1|| m<1)
return -1;
vector<int> res;
for(int i=0;i<n;i++)
res.push_back(i);
int i=0;
while(res.size()>1)
{
i=(i+m-1)%res.size();
res.erase(res.begin()+i);
}
return res[0];
}
2.归纳法:每次加m,分别对n、n-1、n-2、…2、1进行取余数;
int LastRemaining_Solution(int n, int m)
{
if(n<1 || m<1)
return -1;
int s=0;
for(int i=1;i<n+1;i++)
s=(s+m)%i;
return s;
}
3.暴力法:虽然不好,但是也可以锻炼思维;
class Solution {
public:
int LastRemaining_Solution(int n, int m)
{
if(n<1 || m<1)
return -1;
vector<int> child(n,0);
int i=0;
int k=0;
while(i<n-1)
{
int j=0;
while(j<m-1)
{
if(child[k]==0)
{
j++;
}
k=(k+1)%n;
}
while(child[k]==1)
k=(k+1)%n;
child[k]=1;
i++;
}
for(i=0;i<n;i++)
if(child[i]==0)
return i;
}
};
11.减绳子(各段乘最大):
题目
1.类推法:趋于中间的两数乘最大,先处理number<=3的,在使用vec初始化,每次入(v[j]*v[j-i]);
2.数学法:先处理number<=3情况,再处理number>5时: number%3取余数分类讨论;
取幂次方pow(3,n)