提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
蓝桥杯考前抱佛脚,目前学到哪算哪。
一、基础数论
1.最大公约数
最大公约数(Greatest Common Divisor,简称GCD)
辗转相除法(欧几里德法)
原理:
g c d ( a , b ) = g c d ( b , a % b )
当b=0时,gcd(a,b)=a,否则根据公式继续迭代。
int gcd(int a,int b){
if(b==0) {
return a;
}
return gcd(b,a%b);
}
2.最小公倍数
最小公倍数(Least Common Multiple 简称LCM )
定义: a, b的所有公共的倍数中最小的公倍数。
int gcd(int a,int b){
if(b==0) {
return a;
}
return gcd(b,a%b);
}
int lcm(int a,int b){
return a*b/gcd(a,b);
}
3.素数及其判定
素数(也称质数): 一个正整数n是素数当且仅当只能被1和其自身整除,否则就称n是合数 。
注: 1既不是素数也不是合数,最小的素数是2
1.暴力枚举
原理: 循环遍历i从2到 ,只要存在 n % i = 0 即可判定n不是素数
bool isprime (int n){
for(int i=2;i*i<=n;i++){
if(n%i==0) return false;
}
return true;
}
2. 埃拉托斯特尼筛法,简称埃氏筛
是一种用来求自然数n以内的全部素数的方法 。
原理: 一个合数必然可以表示一个质数和另一个数相乘。对于一个素数p,那么p的倍。数2p,3p,…kp,…必然都是合数
const int maxn=1e5+100;
int m;
bool isprime[maxn];
int p[maxn];
void sizee(int n)
{
m=0;memset(isprime,true,sizeof(isprime)); //true 是质数
for(int i=2;i<=n;i++){
if(isprime[i]){
p[++m]=i;
for(int j=2*i;j<=n;j+=i){
isprime[j]=false;
}
}
}
}
二、大数处理
读入存储大数
用整形数组从低位到高位存储这两个大数 ,倒着存放方便计算jin
string num1 ,num2;
cin>>num1>>num2;
//获取两个大数的位数
int n=num1.length(),m=num2.length();
int a[n],b[m];//定义两个整形数组用于待会存储这两个大数的每一位
int i,j;
//用整形数组从低位到高位存储这两个大数
for(i=0,j=n-1;i<n;i++,j--)
a[i]=num1[j]-'0';
for(i=0,j=m-1;i<m;i++,j--)
b[i]=num2[j]-'0';
大数加法
int n=num1.length(),m=num2.length();
int max=m>n?m:n +1;
//int a[max]={0},b[max]={0},c[max]={0};
int i,j;
for(i=0;i<max;i++)//初始化
a[i]=0;
for(i=0;i<max;i++)//初始化
b[i]=0;
for(i=0;i<max;i++)//初始化
c[i]=0;
for(i=0,j=n-1;i<n;i++,j--){
a[i]=num1[j]-'0';
}
for(i=0,j=m-1;i<m;i++,j--){
b[i]=num2[j]-'0';
}
for(i=0;i<max;i++){
c[i]+=a[i]+b[i];
if(c[i]>=10){ // 进位处理
c[i+1]+=1;
c[i]%=10;
}
}
i=max-1;
while(c[i]==0)//去除答案数组c中高位上的0
i--;
while(i>=0)//c[i]是从高位向前看第一个不为0的数
printf("%d",c[i--]);
cout<<endl;
大数减法
大数减法用位数大数减小数,简化过程
int n=num1.length(),m=num2.length();
int max=m>n?m:n +1;
int a[max]={0},b[max]={0},c[max]={0};
if(n<m|| ((n==m)&&num1[0]<num2[0]) ) { //位数相同第一位数字小
string temp=num1;
num1=num2;
num2=temp;
int tmp = n;
n=m;
m=tmp;
}
int i,j;
for(i=0;i<max;i++)//初始化
a[i]=0;
for(i=0;i<max;i++)//初始化
b[i]=0;
for(i=0;i<max;i++)//初始化
c[i]=0;
for(i=0,j=n-1;i<n;i++,j--){
a[i]=num1[j]-'0';
}
for(i=0,j=m-1;i<m;i++,j--){
b[i]=num2[j]-'0';
}
for(i=0;i<max;i++) {
if(a[i]<b[i]){
a[i]+=10; // 借1模拟
a[i+1]--;
}
c[i]=a[i]-b[i];
}
i=max-1;
while(c[i]==0)//去除答案数组c中高位上的0
i--;
while(i>=0)//c[i]是从高位向前看第一个不为0的数
printf("%d",c[i--]);
cout<<endl;
大数乘法
大数乘法关键 c[i+j]+=a[i]*b[j]
int n=num1.length(),m=num2.length();
int a[n],b[m];
int i,j;
for( i=0,j=n-1;i<n;i++,j--){
a[i]=num1[j]-'0';
}
for(i=0,j=m-1;i<m;i++,j--){
b[i]=num2[j]-'0';
}
int c[3000]={0};
for(i=0;i<n;i++){
for(j=0;j<m;j++){
c[i+j]+=a[i]*b[j];
c[i+j+1]+=c[i+j]/10; //处理进位的情况
c[i+j]%=10;
}
}
for(j=2999;j>0;j--){
if(c[j]!=0) //倒着找第一个不为0的数
break;
}
for(i=j;i>=0;i--)
printf("%d",c[i]);
printf("\n");
迷宫问题
S开始,T出口,* 墙壁 输出最小步数
深度优先搜索
#include <bits/stdc++.h>
using namespace std;
/*
3 4
S**
....
***T
*/
int n, m;
string maze[110];
bool vis[110][110];
int dir[4][2] = { {-1,0},{0,-1},{1,0},{0,1} };
int ans = 10000;
bool in(int x, int y) {
return 0 <= x && x < n && 0 <= y && y < m;
}
void dfs(int x, int y, int step) {
if (step >= ans) {
return;
}
if (maze[x][y] == 'T') {
ans = step;
return;
}
vis[x][y] = true;
for (int i = 0; i < 4; i++) {
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if (in(tx, ty) && maze[tx][ty] != '*' && !vis[tx][ty]) {
dfs(tx, ty, step + 1);
}
}
vis[x][y] = false;
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
cin >> maze[i];
}
int x, y;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (maze[i][j] == 'S') {
x = i, y = j;
break;
}
}
}
dfs(x, y, 0);
cout << ans;
}
广度优先搜索
/*
3 4
S**
....
***T
*/
#include <bits/stdc++.h>
using namespace std;
struct node{
int x,y,step;
node(int tx,int ty,int ts){
x=tx;
y=ty;
step=ts;
}
};
int n, m;
string maze[110];
bool vis[110][110];
int dir[4][2] = { {-1,0},{0,-1},{1,0},{0,1} };
int ans =-1;
int main(){
cin >> n >> m;
for (int i = 0; i < n; i++) {
cin >> maze[i];
}
int x, y;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (maze[i][j] == 'S') {
x = i, y = j;
break;
}
}
}
queue<node> q;
q.push(node(x,y,0));
vis[x][y]=true;
while(!q.empty()){
node now=q.front();
q.pop();
for(int i=0;i<4;i++){
int tx=now.x+dir[i][0];
int ty=now.y+dir[i][1];
if(tx<0||tx>=n||ty<0||ty>=m) continue;
if(!vis[tx][ty]&&maze[tx][ty]!='#'){
if(maze[tx][ty]=='T'){
ans=now.step+1;
}else {
vis[tx][ty]=true;
q.push(node(tx,ty,now.step+1));
}
}
}
}
cout << ans;
}