- 辗转相除法求最大公约数
1 int gcd(int a, int b)
2 {
3 if (b == 0) return a;
4 else return gcd(b, a % b);
5 }
- 二分查找(找到位置并插入)
1 /* nums[]指的是有序数组;low指的是数组下标0;high指的是数组下标n-1(n指的是数组长度);target指的是要插入的目标元素 */
2 void sort(int nums[],int low,int high,int target) {
3 int n=high+1; //此时n的值为数组的长度
4 // 当low<=high一直循环折半查找,当low>high时结束循环
5 while(low<=high) {
6 int mid=(low+high)/2;// 计算中间下标
7 if(nums[mid]>=target) { // 如果大于等于要插入的元素,则high=mid-1
8 high=mid-1;
9 } else if(nums[mid]<target) { // 如果小于要插入的元素,在low=mid+1
10 low=mid+1;
11 }
12 } //此时已经查找结束
13 // 然后将nums[high+1]之后的所有元素(包括nums[high+1])向后移动一个位置
14 for(int i=n; i>high+1; i--) { //向后移动,则从后往前一次后移
15 nums[i]=nums[i-1];
16 }
17 // 然后将空出来的nums[high+1]赋为target值
18 nums[high+1]=target;
19 }
3.错排:
当n个编号元素放在n个编号位置,元素编号与位置编号各不对应的方法数用D(n)表示,那么D(n-1)就表示n-1个编号元素放在n-1个编号位置,各不对应的方法数,其它类推.
第一步,把第n个元素放在一个位置,比如位置k,一共有n-1种方法;
第二步,放编号为k的元素,这时有两种情况:⑴把它放到位置n,那么,对于剩下的n-1个元素,由于第k个元素放到了位置n,剩下n-2个元素就有D(n-2)种方法;⑵第k个元素不把它放到位置n,这时,对于这n-1个元素,有D(n-1)种方法;
综上得到
D(n) = (n-1) [D(n-2) + D(n-1)]
特殊地,D(1) = 0, D(2) = 1.
例:例装错信封的问题(经典原型)写n封信,全部装错信封,求有多少种全部装错的方式
#include<iostream>
using namespace std;
int main() {
int n;
long long d[21] = {0,0,1};//将d[0],d[1],d[2]初始化
for(int i=3;i<=20;i++) {
d[i] = (i-1)*(d[i-1]+d[i-2]);
}
while(cin >> n) {
cout << d[n] <<endl;
}
return 0;
}
4.快速幂取模(余数)
1.如果b是偶数,我们可以记k = a^2mod c,那么求(k)b/2 mod c就可以了。
2.如果b是奇数,我们也可以记k =a^2 mod c,那么求 ((k)^b/2 mod c * a) mod c 就可以了。
int PowerMod(int a, int b, int c)
{ //所求为a^b%c
int ans = 1;
a = a % c;
while(b>0)
{
if(b % 2 = = 1) //如果b为奇数,则多一步运算:ans mod c *a=ans*a mod c
ans = (ans * a) % c;
b = b/2;
a = (a * a) % c;
}
return ans;
}
5.快速排序:
void Quick_Sort(int *arr, int begin, int end){
if(begin > end)
return;
int tmp = arr[begin]; //设置基准值tmp
int i = begin; //哨兵i为第一位
int j = end; //哨兵j为最后一位
while(i != j){
while(arr[j] >= tmp && j > i)
j--; //哨兵j先出动,寻找小于tmp的数,找到后退出循环
while(arr[i] <= tmp && j > i)
i++; //哨兵i后出动,寻找大于tmp的数
if(j > i){ //找到后交换arr[i] arr[j]
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
} //当i=j时,第一轮快速排序结束,需要将tmp与arr[i]/arr[j]交换
arr[begin] = arr[i];
arr[i] = tmp;
//此时基准值已经到了分界点位置,再分别对左边和右边重复进行快速排序
Quick_Sort(arr, begin, i-1);
Quick_Sort(arr, i+1, end);
}
- 进制转换
#include<stdio.h>
int main() {
int n;
scanf("%X",&n); //输入十六进制
printf("%lld",n); //输出十进制
return 0;
}
%c 读入一个字符
%d 读入十进制整数
%i 读入十进制,八进制,十六进制整数
%o 读入八进制整数
%x,%X 读入十六进制整数
%s 读入一个字符串,遇空格、制表符或换行符结束。
%f,%F,%e,%E,%g,%G 用来输入实数,可以用小数形式或指数形式输入。
%p 读入一个指针
%u 读入一个无符号十进制整数
%% 读%符号
#include <stdio.h>
#include <stdlib.h>
int main() {
int a;
scanf("%X",&a); //输入十六进制
printf("%o",a); //输出八进制
return 0;
}
7.素数
#include <stdio.h>
int main() {
int n;
printf("请输入一个1-100之间的整数:\n");
scanf("%d", &n);
int m = 0;
for (int i = 2; i < n/i; i++ ) {
if(n % i == 0) {
m++; //素数的因数+1
}
}
if (m == 0) {
printf("%d是素数\n", n);
} else {
printf("%d不是素数\n", n);
}
return 0;
}
- 排序sort——头文件为#include
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
int a[10] = { 1,3,4,2,5,6,7,9,8,0 };
sort(a, a + 10); //默认为从小到大排序
/*
如果想改为从大到小排序,可写作:
sort(a,a+10,greater<int>);
*/
for (int i = 0; i < 10; i++) {
cout << a[i] << " ";
}
return 0;
}
- 常用函数
见该文章https://blog.csdn.net/weixin_45920495/article/details/103594844
-
背包动态规划
不会 -
参考自:(DFS?)
https://blog.csdn.net/weixin_45920495/article/details/123366365
- C语言编程复习
http://c.biancheng.net/c/example/