1、数论
浮点数比较及Pi的定义
1 //浮点数比较及Pi的定义 2 #include<cstdio> 3 #include<cmath> 4 5 using namespace std; 6 7 const double eps = 1e-8; 8 const double Pi = acos(-1.0); 9 10 11 #define Equ(a, b) ((fabs((a) - (b))) < (eps)) 12 #define More(a, b) (((a) - (b)) > (eps)) 13 #define Less(a, b) (((a) - (b)) < (-eps)) 14 #define MoreEqu(a, b) (((a) - (b)) > (-eps)) 15 #define LessEqu(a, b) (((a) - (b)) < (eps))
排列组合
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 11; 5 //P为当前排列,hashTable记录整数x是否已经在P中 6 int n, P[maxn], hashTable[maxn] = {false}; 7 8 //当前处理排列的第index位 9 void generateP(int index) 10 { 11 //递归边界,已经处理完排列的1 ~ n位 12 if(index == n + 1) 13 { 14 for(int i = 1; i <=n ; ++i) 15 { 16 cout << P[i]; 17 } 18 cout << endl; 19 return; 20 } 21 //枚举1 ~ n 位,试图将x填入P[index] 22 for(int x = 1; x <= n; x++) 23 { 24 if(hashTable[x] == false) 25 { 26 P[index] = x; 27 hashTable[x] = true; 28 generateP(index + 1); 29 hashTable[x] = false; 30 } 31 } 32 } 33 34 int main() 35 { 36 n = 1; 37 generateP(1); 38 return 0; 39 }
快速幂
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 6 LL binaryPow(LL a, LL b) 7 { 8 if(b == 0) return 1; 9 if(b % 2 == 1) return a * binaryPow(a, b - 1); 10 else 11 { 12 LL mul = binaryPow(a, b / 2); 13 return mul * mul; 14 } 15 } 16 17 int main() 18 { 19 cout << binaryPow(3, 3) << endl; 20 return 0; 21 }
最大公约数(gcd)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int gcd(int a, int b) 5 { 6 return !b? a : gcd(b, a % b); 7 } 8 9 int main() 10 { 11 int a, b; 12 while(cin >> a >> b) 13 { 14 if(a < b) swap(a, b); 15 cout << gcd(a, b) << endl; 16 } 17 return 0; 18 }
最小公倍数(lcm)
#include <bits/stdc++.h> using namespace std; int gcd(int a, int b) { if(a < b) swap(a, b); return !b ? a : gcd(b, a % b); } int lcm(int a, int b) { int d = gcd(a, b); return a / d * b; }
分数相关
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int gcd(long a, long b) 5 { 6 if(a < b) swap(a, b); 7 return !b ? a : gcd(b, a % b); 8 } 9 10 //定义 11 typedef struct fraction 12 { 13 long up; 14 long down; 15 }frac; 16 17 //化简 18 frac reduction(frac res) 19 { 20 if(res.down < 0) 21 { 22 res.down = -res.down; 23 res.up = -res.up; 24 } 25 26 if(res.up == 0) 27 { 28 res.down = 1; 29 } 30 else 31 { 32 int d = gcd(abs(res.up), abs(res.down)); 33 res.up = res.up / d; 34 res.down = res.down / d; 35 } 36 37 return res; 38 } 39 40 //相加 41 frac add(frac f1, frac f2) 42 { 43 frac res; 44 res.up = f1.up * f2.down + f2.up * f1.down; 45 res.down = f1.down * f2.down; 46 return reduction(res); 47 }
素数的判断
1 bool isPrime(int n) 2 { 3 if(n <= 1) return false; 4 int sqr = (int)sqrt(1.0 * n); 5 for(int i = 2; i <= sqr; i++) 6 { 7 if(n % i == 0) return false; 8 } 9 10 return true; 11 }
素数表的获取
埃氏筛(O(nloglogn))
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 101;//表长 5 int prime[maxn], pNum = 0;//prime数组存放所有素数, pNum为素数个数 6 bool p[maxn] = {0};//如果i为素数,则p[i]为false;否则p[i]为true 7 8 void findPrime() 9 { 10 for(int i = 2; i < maxn; i++) 11 { 12 if(p[i] == false) 13 { 14 prime[pNum++] = i; 15 for(int j = i + i; j < maxn; j += i) //筛去i的所有倍数 16 { 17 p[j] = true; 18 } 19 } 20 } 21 } 22 23 int main() 24 { 25 findPrime(); 26 for(int i = 0; i < pNum; i++) 27 { 28 cout << prime[i] << " "; 29 } 30 cout << endl; 31 32 return 0; 33 }
分解质因子
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 100010; 5 6 /* 7 bool isPrime(int n) 8 { 9 if(n == 1) return false; 10 int sqr = (int)sqrt(1.0 * n); 11 for(int i = 2; i <= sqr; i++) 12 { 13 if(n % i == 0) return false; 14 } 15 16 return true; 17 } 18 */ 19 20 int prime[maxn], pNum = 0; 21 bool p[maxn] = {0}; 22 23 void findPrime() 24 { 25 for(int i = 2; i < maxn; i++) 26 { 27 if(p[i] == 0) 28 { 29 prime[pNum++] = i; 30 for(int j = i + i; j < maxn; j += i) 31 { 32 p[j] = true; 33 } 34 } 35 } 36 } 37 38 struct factor 39 { 40 int x, cnt; 41 }fac[10]; // 对于一个int型范围的数来说, fac数组的大小只需要开到10就可以了 42 43 int main() 44 { 45 findPrime(); 46 int n, num = 0; 47 cin >> n; 48 if(n == 1) cout << "1=1"; 49 else 50 { 51 cout << n << "="; 52 int sqr = (int)sqrt(1.0 * n); 53 for(int i = 0; i < pNum && prime[i] <= sqr; i++) 54 { 55 if(n % prime[i] == 0) 56 { 57 fac[num].x = prime[i]; 58 fac[num].cnt = 0; 59 while(n % prime[i] == 0) 60 { 61 fac[num].cnt++; 62 n /= prime[i]; 63 } 64 num++; 65 } 66 67 if(n == 1) break; 68 } 69 70 if(n != 1)//无法被根号n以内的因子除尽 71 { 72 fac[num].x = n; 73 fac[num++].cnt = 1; 74 } 75 76 for(int i = 0; i < num; i++) 77 { 78 if(i > 0) cout << "*"; 79 cout << fac[i].x; 80 if(fac[i].cnt > 1) 81 { 82 cout << "^" << fac[i].cnt; 83 } 84 } 85 } 86 return 0; 87 }
N 的因子个数=(e1 + 1) *(e2 + 1) * ... *(ek + 1) ei为各因子个数。
大整数
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 //大整数的存储 5 struct bign 6 { 7 int d[1000]; 8 int len; 9 bign()//定义结构体变量时,会自动对该变量进行初始化 10 { 11 memset(d, 0, sizeof(d)); 12 len = 0; 13 } 14 }; 15 16 //字符串转化为大整数 17 bign bignChange(string str) 18 { 19 bign a; 20 a.len = str.size(); 21 for(int i = 0; i < a.len; i++) 22 { 23 a.d[i] = str[a.len - i - 1] - '0'; //逆着赋值 24 } 25 26 return a; 27 } 28 29 //大整数比较 a大 1,相等 0,a小 -1 30 int bignCompare(bign a, bign b) 31 { 32 if(a.len > b.len) 33 { 34 return 1; 35 } 36 else if(a.len < b.len) 37 { 38 return -1; 39 } 40 else 41 { 42 for(int i = a.len - 1; i >= 0; i--) 43 { 44 if(a.d[i] > b.d[i]) 45 { 46 return 1; 47 } 48 else if(a.d[i] < b.d[i]) 49 { 50 return -1; 51 } 52 } 53 return 0; 54 } 55 } 56 57 //高精度加法 (将改位上的两个数字和进位相加,得到的结果取个位数作为该位结果,取十位数作为新的进位) 58 bign bignAdd(bign a, bign b) 59 { 60 bign c; 61 int carry = 0; //进位 62 for(int i = 0; i < a.len || i < b.len; i++)//较长的为界限 63 { 64 int temp = a.d[i] + b.d[i] + carry; 65 c.d[c.len++] = temp % 10; 66 carry = temp / 10; 67 } 68 if(carry != 0)//最后进位不为0,则直接赋值给最高位 69 { 70 c.d[c.len++] = carry; 71 } 72 return c; 73 } 74 75 //高精度减法 a - b (需要比较大小,如果被减数小于减数,要交换两个变量,然后输出负号) 76 bign bignSub(bign a, bign b) 77 { 78 bign c; 79 for(int i = 0; i < a.len || i < b.len; i++) 80 { 81 if(a.d[i] < b.d[i]) 82 { 83 a.d[i + 1]--; 84 a.d[i] += 10; 85 } 86 c.d[c.len++] = a.d[i] - b.d[i]; 87 } 88 89 while(c.len - 1 >= 1 && c.d[c.len - 1] == 0) 90 { 91 c.len--;//去除最高位的0,同时至少保留一位最低位 92 } 93 94 return c; 95 } 96 97 //高精度与低精度的乘法 (始终将低精度数作为一个整体) 98 bign bignMul(bign a, int b) 99 { 100 bign c; 101 int carry = 0; 102 for(int i = 0; i < a.len; i++) 103 { 104 int temp = a.d[i] * b + carry; 105 c.d[c.len++] = temp % 10; 106 carry = temp / 10; 107 } 108 while(carry != 0) 109 { 110 c.d[c.len++] = carry % 10; 111 carry /= 10; 112 } 113 114 return c; 115 } 116 117 bign bignDiv(bign a, int b, int& r)//r为余数 118 { 119 bign c; 120 c.len = a.len;//被除数的每一位和商的每一位是一一对应的 121 for(int i = a.len - 1; i >= 0; i--) 122 { 123 r = r * 10 + a.d[i]; 124 if(r < b) 125 { 126 c.d[i] = 0; 127 } 128 else 129 { 130 c.d[i] = r / b; 131 r = r % b; 132 } 133 } 134 135 while(c.len - 1 >= 1 && c.d[c.len - 1] == 0) 136 { 137 c.len--; 138 } 139 return c; 140 } 141 142 void bignPrint(bign a) 143 { 144 for(int i = a.len - 1; i >= 0; i--) 145 { 146 cout << a.d[i]; 147 } 148 cout << endl; 149 } 150 151 int main() 152 { 153 string s1, s2; 154 cin >> s1 >> s2; 155 bign b1 = bignChange(s1); 156 bign b2 = bignChange(s2); 157 158 bignPrint(bignAdd(b1, b2)); 159 bignPrint(bignSub(b1, b2)); 160 bignPrint(bignMul(b1, 2)); 161 int r = 0; 162 bignPrint(bignDiv(b1, 2, r)); 163 164 return 0; 165 }
ax + by = gcd(a, b)的求解
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int exGcd(int a, int b, int &x, int &y) 5 { 6 if(b == 0) 7 { 8 x = 1; 9 y = 0; 10 return a; 11 } 12 13 int g = exGcd(b, a % b, x, y); 14 int temp = x; 15 x = y; 16 y = temp - a / b * y; 17 return g; 18 } 19 20 int main() 21 { 22 int x, y; 23 int g = exGcd(25, 15, x, y); 24 printf("25 * %d + 15 * %d = %d ", x, y, g); 25 26 //k为任意整数,经过一下运算后得到全部解 27 int xx, yy, k; 28 xx = x + 15 / g * k; 29 yy = y - 25 / g * k; 30 31 printf("25 * %d + 15 * %d = %d ", xx, yy, g); 32 33 return 0; 34 }
组合数的计算
组合数是指在n个元素中选出m个元素的方案数
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 6 LL C(LL n, LL m) 7 { 8 LL ans = 1; 9 for(LL i = 1; i <= m; i++) 10 { 11 ans = ans * (n - m + i) / i; 12 } 13 return ans; 14 } 15 int main() 16 { 17 int n, m; 18 while(cin >> n >> m) 19 { 20 cout << C(n, m) << endl; 21 } 22 return 0; 23 }
组合数 % p
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 6 LL C(LL n, LL m) 7 { 8 LL ans = 1; 9 for(LL i = 1; i <= m; i++) 10 { 11 ans = ans * (n - m + i) / i; 12 } 13 return ans; 14 } 15 16 int Lucas(int n, int m) 17 { 18 if(m == 0) return 1; 19 return C(n % p, m % p) * Lucas(n / p, m / p) % p; 20 }
2、排序
归并排序
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 100; 5 //将数组A的[L1, R1]与[L2, R2]区间合并为有序区间(此处L2即为R1 + 1) 6 void merge(int A[], int L1, int R1, int L2, int R2) 7 { 8 int i = L1, j = L2; 9 int temp[maxn], index = 0; 10 while(i <= R1 && j <= R2) 11 { 12 if(A[i] <= A[j]) 13 { 14 temp[index++] = A[i++]; 15 } 16 else 17 { 18 temp[index++] = A[j++]; 19 } 20 } 21 22 while(i <= R1) temp[index++] = A[i++]; 23 while(j <= R2) temp[index++] = A[j++]; 24 for(i = 0; i < index; i++) 25 { 26 A[L1 + i] = temp[i]; 27 } 28 } 29 30 /* 31 void mergeSort(int A[], int left, int right) 32 { 33 if(left < right) 34 { 35 int mid = (left + right) / 2; 36 mergeSort(A, left, mid); 37 mergeSort(A, mid + 1, right); 38 merge(A, left, mid, mid + 1, right); 39 } 40 } 41 */ 42 43 void mergeSort(int A[], int n) 44 { 45 for(int step = 2; step / 2 < n; step *= 2) 46 { 47 for(int i = 0; i <= n; i += step) 48 { 49 int mid = i + step / 2 - 1; 50 if(mid + 1 <= n) 51 { 52 merge(A, i, mid, mid + 1, min(i + step - 1, n)); 53 } 54 } 55 } 56 } 57 58 int main() 59 { 60 int a[10] = {9,8,7,6,5,4,3,2,1,0}; 61 mergeSort(a, 9); 62 for(int i = 0; i < 10; i++) 63 { 64 cout << a[i] << " "; 65 } 66 cout << endl; 67 return 0; 68 }
3、字符串
整型与字符串相互转换
1 #include <iostream> 2 #include <cstdio> 3 #include <string> 4 5 using namespace std; 6 7 int main(){ 8 //字符串转整型 9 string s = "123"; 10 cout << atoi(s.c_str()) << endl; 11 12 //整形转字符串 13 int i = 123; 14 cout << to_string(i) << endl; 15 16 17 return 0; 18 }
3、二分
(1)二分查找指定元素所在位置
1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 6 int binarySearch(int A[], int left, int right, int target) 7 { 8 while(left <= right) 9 { 10 int mid = left + (right - left) / 2; 11 if(A[mid] == target) return mid; 12 else if(A[mid] < target) left = mid + 1; 13 else right = mid - 1; 14 } 15 return -1; 16 } 17 18 int main() 19 { 20 int a[10] = {1,2,3,4,5,6,7,8,9,10}; 21 22 cout << binarySearch(a, 0, 9, 5) << endl; 23 24 return 0; 25 }
(2)二分查找序列中第一个大于等于给定元素的位置
1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 6 int binarySearch(int A[], int left, int right, int target) 7 { 8 while(left < right) 9 { 10 int mid = left + (right - left) / 2; 11 if(A[mid] >= target) right = mid ; 12 else left = mid + 1; 13 } 14 return left; 15 } 16 17 int main() 18 { 19 int a[10] = {1,2,3,4,5,6,7,8,9,10}; 20 21 cout << binarySearch(a, 0, 9, 5) << endl; 22 23 return 0; 24 }
(3)二分查找序列中第一个大于给定元素的位置
1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 6 int binarySearch(int A[], int left, int right, int target) 7 { 8 while(left < right) 9 { 10 int mid = left + (right - left) / 2; 11 if(A[mid] > target) right = mid ; 12 else left = mid + 1; 13 } 14 return left; 15 } 16 17 int main() 18 { 19 int a[10] = {1,2,3,4,5,6,7,8,9,10}; 20 21 cout << binarySearch(a, 0, 9, 5) << endl; 22 23 return 0; 24 }