负数如何在计算机中表示
-x = ~x + 1
1 = 0000 0000 0000 0000 0000 0000 0000 0001
~1 = 1111 1111 1111 1111 1111 1111 1111 1110
-1 = 1111 1111 1111 1111 1111 1111 1111 1111
最大公约数和最小公倍数
求最大公约数
写法一
int gcd(int a,int b){
return y == 0?x:gcd(b,a%b);
}
写法二
int gcd(int a,int b){
return a%b?gcd(b,a%b):b;
}
求最小公倍数
int x = a*b/gcd(a,b);
数论O(1)
如果 a,ba,b 均是正整数且互质,那么由 ax+by,x≥0,y≥0ax+by,x≥0,y≥0 不能凑出的最大数是 ab−a−b。
两个数的最大公约数为1
(p,q) = 1;
不能由p和q凑出来的最大的数是(p-1)(q-1)-1
例题
小明开了一家糖果店。
他别出心裁:把水果糖包成4颗一包和7颗一包的两种。
糖果不能拆包卖。
小朋友来买糖的时候,他就用这两种包装来组合。
当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。
你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。
大于17的任何数字都可以用4和7组合出来。
本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。
输入格式
两个正整数 n,m,表示每种包装中糖的颗数。
输出格式
一个正整数,表示最大不能买到的糖数。
数据范围
2≤n,m≤1000,
保证数据一定有解。
输入样例:
4 7
输出样例:
17
#include<iostream>
using namespace std;
int main(){
int n,m;
cin >> n >> m;
cout << n*m - n - m << endl;
return 0;
}
数列求和公式
等差数列:
通项公式:an = a1 + (n-1)d
求和公式:sn = na1 + n(n-1)*d/2 = n*(a1 + an)/2
等比数列:
通项公式:an = a1 * q ^ (n - 1)
求和公式:sn = a1 * (1 - q ^ n)/(1-q)
一维差分
给定a[1],a[2],a[3]...
构造差分数组b[N],使得a[i] = b[1] + b[2] + ... + b[i]
#核心操作
将a[L~R]全部加上c,等价于:
b[L] += c,b[R + 1] -= c(个人理解就是一个内层递推原理)
时间复杂度优化 O(n) ---> O(1)
二维差分
给定原矩阵a[i,j]构造差分矩阵b[i,j],使得a[][]是b[][]的二维前缀和
core operation
以a[x1][y1]为左上角,a[x2][y2]为右下角的子矩阵所有的数a[i][j] 加 c;
S[x1][x2] += c;
S[x1][y2 + 1] -= c;
S[x2 + 1][y1] -= c;
S[x2 + 1][y2 + 1] += c;
双指针
将O(n^2)复杂度优化为O(n)
#经典案例
按空格分割字符串
#include<iostream>
#include<string.h>
using namespace std;
int main(){
char a[1000];
gets(a);
int n = strlen(a);
for(int i = 0;i < n;i++){
int j = i;
#核心代码逻辑
while(j < n && a[j] != ' ') j++;
for(int k = i;k < j;k++) cout << a[k];
cout << endl;
i = j;
}
return 0;
}
BFS
#队列 先进先出 bfs
#栈 先进后出(递归形式表示) dfs
关于mod的神奇推理
给定数列1, 1, 1, 3, 5, 9, 17, …,从第4 项开始,每项都是前3 项的和。求
第20190324 项的最后4 位数字。
公式:a%10000 + b%10000 + c%10000 = (a+b+c)%10000
#include<iostream>
using namespace std;
typedef long long LL;
int a=1,b=1,c=1;
LL ans(int n){
int res = 0;
for(int i = 4;i <= n;i++){
res = a + b + c;
if(res > 10000){
res %=10000;
}
a = b,b = c, c = res;
}
return res;
}
int main(){
int n = 20190324 ;
cout << ans(n) << endl;
return 0;
}
均值不等式
x1 + x2 + … + xn = c
则有:(x^2表示x的平方)
(x1^2 + x2^2 +...+ xn^2)/2 >= (x1+x2+x3+...+xn)^2/2
且当x1 == x2 == x3 ==..==xn == c/n时取到最小值
isdigit(char(c));字符串中字符c是否是否是数字
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if (matrix.empty() || matrix[0].empty()) return false;
int n = matrix.size(), m = matrix[0].size();
int l = 0, r = n * m - 1;
while (l < r)
{
int mid = (l + r) / 2;
if (matrix[mid / m][mid % m] >= target) r = mid;
else l = mid + 1;
}
return matrix[r / m][r % m] == target;
}
};
中位数/列数=第几行,中位数%列数=第几列的第几个数,定位二维数组太庙啦!
坐标(x1,y1)(x2,y2)之间的曼哈顿距离是abs(x1 - x2) + abs(y1 - y2) - 1
OK,懂了,谢谢大佬
这个第一个数论那里写的有点看不懂
我加了一个例题你可以看下 就是求一个由互质的两个数不能凑出来的最大的数,结论 一般要求记住就好