计算机专业保研本校机考,GitHub - Lambert-hpx/cs-baoyan-kaoyan-jikao-zhengli: 计算机保研考研上机考试复习整理,制作不易,还请给个star噢~...

复习目录

常用函数:STL等常用数据结构(树、栈、队列、优先队列、向量、散列表、集合、字符串)和函数

数学问题(最小公倍数、最大公因数、快速幂、进制转换、质因数、大数)

搜索(BFS & DFS)

图论(并查集、最小生成树、最短路径、拓扑排序、关键路径)

动态规划

常用函数

memset-对数组中每个元素赋值0/-1

#include

int a[5];

memset(a,0,sizeof(a));

getchar/putchar && gets/puts

#include

getchar(); //输入单个字符 有时候还可以用来吸收换行符

putchar(); //输出单个字符

gets(); //输入一行字符串,识别\n作为输入结束

puts(); //输出一行字符串,并输出\n 若是字符串末尾没有\0则会乱码

string.h

#include

strlen(str);

strcmp(str1,str2);

//比较字典序,小于返回负整数,等于返回0,大于返回正整数

strcpy(str1,str2); //把str2复制给str1

strcat(str1,str2); //把str2接到str1后面

math.h

#include

fabs(-12.56); //12.56

floor(-5.2); //-6 向下(小)取整

ceil(-5.2); //5 向上(大)取整

double db = pow(2.0,3.0); //8.000000

sqrt(2.0); //1.414214

log(1.0); //0.000000 以自然对数为底的对数

//log(a)b=logb/loga 必须用换底公式

const double pi = acos(-1.0);

sin(pi*45/180);

cos(pi*45/180);

tan(pi*45/180); //弧度制!!

asin(1);

acos(-1.0);

atan(0);

round(3.5); //4 四舍五入

printf

#include

#include

%5d; //宽为5的整数,超过5位按实际输出,不够5位右对齐输出

%05d; //宽为5的整数,超过5位按实际输出,不够5位前置补0右对齐

%5.2f; //宽为5的浮点数,小数点有2位,小数点占一位, 不够5位右对齐输出

%6.9s; //表示显示一个长度不小于6且不大于9的字符串。若大于9, 则第9个字符以后的内容将被删除。

%ld; //表示输出long整数

%lf; //表示输出double浮点数

%-7d; //表示输出7位整数左对齐 空位补齐

%-10s; //表示输出10个字符左对齐

/*按整型输出,默认右对齐*/

printf("%d\n",PrintVal);

/*按整型输出,补齐4位的宽度,补齐位为空格,默认右对齐*/

printf("%4d\n",PrintVal);

/*按整形输出,补齐4位的宽度,补齐位为0,默认右对齐*/

printf("%04d\n",PrintVal);

/*按16进制输出,默认右对齐*/

printf("%x\n",PrintVal);

/*按16进制输出,补齐4位的宽度,补齐位为空格,默认右对齐*/

printf("%4x\n",PrintVal);

/*按照16进制输出,补齐4位的宽度,补齐位为0,默认右对齐*/

printf("%04x\n",PrintVal);

/*按8进制输出,默认右对齐*/

printf("%o\n",PrintVal);

/*按8进制输出,补齐4位的宽度,补齐位为空格,默认右对齐*/

printf("%4o\n",PrintVal);

/*按照8进制输出,补齐4位的宽度,补齐位为0,默认右对齐*/

printf("%04o\n",PrintVal);

常用模板代码

日期转换

闰年判断

bool IsLeapYear(int year){

return (year%4==0 && year%100!=0) || (year%400==0);

}

反序数

int Reverse(int x){

int revx=0;

while(x != 0){

revx*=10;

revx+=x%10;

x/=10;

}

return revx;

}

最大公约数 & 最小公倍数

//最大公约数求法

int GCD(int a,int b){ //辗转相除法 a大b小

if(b==0){

return a;

}else{

return GCD(b,a%b);

}

}

//最小公倍数求法

a * b / GCD(a,b);

质数和分解质因数

1. 质数判定:若到sqrt(n)的整数,所有正整数均不能整除n,则可以判断n为素数(小于2必定不是素数)

2. 某范围内的素数筛法

const int MAXN = 10001;

vector prime; //保存质数

bool isPrime[MAXN]; //标记数组

void Initial(){

//初始化

for(int i=0;i

isPrime[i] = true;

}

isPrime[0]=false;

isPrime[1]=false;

//素数筛法

for(int i = 2;i

if(!isPrime[i]){ //非质数跳过

continue;

}

prime.push_back(i);

for(int j=i*i;j

isPrime[j]=false; //质数的倍数必为非质数

}

}

}

3. 分解质因数:先用素数筛法,然后不断试除

快速幂

求指数的二进制数

求底数幂然后累乘

矩阵快速幂,初始化为单位矩阵

int FastExp(int a,int b,int mod){

int answer = 1; //初始化为1

while(b!=0){ //不断将b转换为二进制数

if (b%2==1){ //若位为1,累乘a的2^k次幂

answer *= a;

//answer %= mod; //求后三位,依题目而定

}

b/=2; //b不断转换

a*=a; //a不断平方

//a%=mod; //求后三位,依题目而定

}

return a

同余模定理

(a*b)%c=((a%c)*(b%c))%c;

(a+b)%c=((a%c)+(b%c))%c;

BFS

#include

#include

#define SIZE 1000

using namespace std;

queue q_x, q_y, q_pos;

int step[4][2] = {

{1,0},{0,1},{-1,0},{0,-1}

};

int m, n, board[SIZE][SIZE], start_x, start_y, target_x, target_y;

bool vis[SIZE][SIZE];

void bfs() {

bool flag = false; //判断是否成功的标志

while (!q_x.empty() && !q_y.empty()) { //判断队是否为空

for (int k = 0; k < 4; ++k) { //先遍历

int tx = q_x.front() + step[k][0]; //状态转移

int ty = q_y.front() + step[k][1];

if (tx < 1 || ty < 1 || tx > n || ty > m) //判断边界

continue;

if (!board[tx][ty] && !vis[tx][ty]) {

vis[tx][ty] = true; //标记

q_x.push(tx); //入队

q_y.push(ty);

q_pos.push(q_pos.front() + 1);

}

if (tx == target_x&&ty == target_y) { //判断到达目标的条件

flag = true;

break;

}

}

if (flag)

break;

q_x.pop(); //队首出队

q_y.pop();

q_pos.pop();

}

return;

}

int main()

{

while (cin >> m >> n) {

for (int i = 1; i <= m; ++i) {

for (int j = 1; j <= n; ++j) {

cin >> board[i][j];

}

}

cin >> start_x >> start_y >> target_x >> target_y;

q_x.push(start_x);

q_y.push(start_y); //初始入队

q_pos.push(0);

vis[start_x][start_y] = true;

bfs();

cout << q_pos.back() << endl;

}

return 0;

}

DFS

int check(参数)

{

if(满足条件)

return 1;

return 0;

}

void dfs(int step)

{

判断边界

{

相应操作

}

尝试每一种可能

{

满足check条件

标记

继续下一步dfs(step+1)

恢复初始状态(回溯的时候要用到)

}

}

并查集

用于判断图是否为连通图

求图的连通分量

#include

#include

using namespace std;

const int MAXN = 1000;

int father[MAXN]; //父亲结点

int height[MAXN]; //结点高度

void Initial(int n){ //初始化

for(int i=0;i<=n;i++){

father[i]=i; //每个结点的父亲为自己

height[i]=0; //每个结点初始高度为0

}

}

int Find(int x){ //查找根节点

if(x!=father[x]){ //路径压缩

father[x]=Find(father[x]);

}

return father[x];

}

void Union(int x,int y){ //合并集合

x=Find(x);

y=Find(y);

if(x!=y){ //矮树作为高数的子树

if(height[x]

father[x]=y;

}else if (height[y]

father[y]=x;

}else{

father[y]=x;

height[x]++;

}

}

return ;

}

//先Initial 再 一个一个输入 Union

//Find(i)==i; 说明有一个集合,即连通分量

最小生成树

连通所有结点的树中权值最小的即为最小生成树,实现同样用了并查集的思想:

Initial 后按边的权值排序

判断边的两个顶点是否同属一个集合 (用Find)

不同集合则合并(Union),加上这条关键边的长度

#include

struct Edge{

int from; //边的起点

int to; //边的终点

int length; //边的长度

friend bool operator < (const Edge& e1,const Edge& e2) const {

return e1.length < e2.length;

}

};

Edge edge[MAXN*MAXN]; //边集

/*上边并查集的所有内容*/

void Kruskal(int n,int edgeNum){ //克鲁斯卡尔算法,n为点数,edgeNum为边数

Initial(n);

sort(edge,edge+edgeNum); //按权值排序,重载运算符,无需重写cmp

int sum=0; //初始化最小生成树长度

for(int i=0;i

Edge current = edge[i];

if (Find(current.from)!=Find(current.to)){ //边的两端结点不同属一个连通子集吗?

Union(current.from,current.to); //不同属的话就合并连通

sum+=current.length; //属于最小生成树的一部分了

}

}

return sum;

}

大数

定义类

#include

#include

#include

#include

#include

using namespace std;

#define MAXN 9999

#define MAXSIZE 10

#define DLEN 4

class BigNum

{

private:

int a[1500]; //可以控制大数的位数

int len; //大数长度

public:

BigNum(){ len = 1;memset(a,0,sizeof(a)); } //构造函数

BigNum(const int); //将一个int类型的变量转化为大数

BigNum(const char*); //将一个字符串类型的变量转化为大数

BigNum(const BigNum &); //拷贝构造函数

BigNum &operator=(const BigNum &); //重载赋值运算符,大数之间进行赋值运算

friend istream& operator>>(istream&, BigNum&); //重载输入运算符

friend ostream& operator<

BigNum operator+(const BigNum &) const; //重载加法运算符,两个大数之间的相加运算

BigNum operator-(const BigNum &) const; //重载减法运算符,两个大数之间的相减运算

BigNum operator*(const BigNum &) const; //重载乘法运算符,两个大数之间的相乘运算

BigNum operator/(const int &) const; //重载除法运算符,大数对一个整数进行相除运算

BigNum operator^(const int &) const; //大数的n次方运算

int operator%(const int &) const; //大数对一个int类型的变量进行取模运算

bool operator>(const BigNum & T)const; //大数和另一个大数的大小比较

bool operator>(const int & t)const; //大数和一个int类型的变量的大小比较

void print(); //输出大数

};

将一个int类型的变量转化为大数

BigNum::BigNum(const int b)

{

int c,d = b;

len = 0;

memset(a,0,sizeof(a));

while(d > MAXN)

{

c = d - (d / (MAXN + 1)) * (MAXN + 1);

d = d / (MAXN + 1);

a[len++] = c;

}

a[len++] = d;

}

将一个字符串类型的变量转化为大数

BigNum::BigNum(const char*s)

{

int t,k,index,l,i;

memset(a,0,sizeof(a));

l=strlen(s);

len=l/DLEN;

if(l%DLEN)

len++;

index=0;

for(i=l-1;i>=0;i-=DLEN)

{

t=0;

k=i-DLEN+1;

if(k<0)

k=0;

for(int j=k;j<=i;j++)

t=t*10+s[j]-'0';

a[index++]=t;

}

}

拷贝构造函数

BigNum::BigNum(const BigNum & T) : len(T.len)

{

int i;

memset(a,0,sizeof(a));

for(i = 0 ; i < len ; i++)

a[i] = T.a[i];

}

重载赋值运算符,大数之间进行赋值运算

BigNum & BigNum::operator=(const BigNum & n)

{

int i;

len = n.len;

memset(a,0,sizeof(a));

for(i = 0 ; i < len ; i++)

a[i] = n.a[i];

return *this;

}

重载输入运算符

istream& operator>>(istream & in, BigNum & b)

{

char ch[MAXSIZE*4];

int i = -1;

in>>ch;

int l=strlen(ch);

int count=0,sum=0;

for(i=l-1;i>=0;)

{

sum = 0;

int t=1;

for(int j=0;j<4&&i>=0;j++,i--,t*=10)

{

sum+=(ch[i]-'0')*t;

}

b.a[count]=sum;

count++;

}

b.len =count++;

return in;

}

重载输出运算符

ostream& operator<

{

int i;

cout << b.a[b.len - 1];

for(i = b.len - 2 ; i >= 0 ; i--)

{

cout.width(DLEN);

cout.fill('0');

cout << b.a[i];

}

return out;

}

两个大数之间的相加运算

BigNum BigNum::operator+(const BigNum & T) const

{

BigNum t(*this);

int i,big; //位数

big = T.len > len ? T.len : len;

for(i = 0 ; i < big ; i++)

{

t.a[i] +=T.a[i];

if(t.a[i] > MAXN)

{

t.a[i + 1]++;

t.a[i] -=MAXN+1;

}

}

if(t.a[big] != 0)

t.len = big + 1;

else

t.len = big;

return t;

}

两个大数之间的相减运算

BigNum BigNum::operator-(const BigNum & T) const

{

int i,j,big;

bool flag;

BigNum t1,t2;

if(*this>T)

{

t1=*this;

t2=T;

flag=0;

}

else

{

t1=T;

t2=*this;

flag=1;

}

big=t1.len;

for(i = 0 ; i < big ; i++)

{

if(t1.a[i] < t2.a[i])

{

j = i + 1;

while(t1.a[j] == 0)

j++;

t1.a[j--]--;

while(j > i)

t1.a[j--] += MAXN;

t1.a[i] += MAXN + 1 - t2.a[i];

}

else

t1.a[i] -= t2.a[i];

}

t1.len = big;

while(t1.a[len - 1] == 0 && t1.len > 1)

{

t1.len--;

big--;

}

if(flag)

t1.a[big-1]=0-t1.a[big-1];

return t1;

}

两个大数之间的相乘运算

BigNum BigNum::operator*(const BigNum & T) const

{

BigNum ret;

int i,j,up;

int temp,temp1;

for(i = 0 ; i < len ; i++)

{

up = 0;

for(j = 0 ; j < T.len ; j++)

{

temp = a[i] * T.a[j] + ret.a[i + j] + up;

if(temp > MAXN)

{

temp1 = temp - temp / (MAXN + 1) * (MAXN + 1);

up = temp / (MAXN + 1);

ret.a[i + j] = temp1;

}

else

{

up = 0;

ret.a[i + j] = temp;

}

}

if(up != 0)

ret.a[i + j] = up;

}

ret.len = i + j;

while(ret.a[ret.len - 1] == 0 && ret.len > 1)

ret.len--;

return ret;

}

大数对一个整数进行相除运算

BigNum BigNum::operator/(const int & b) const

{

BigNum ret;

int i,down = 0;

for(i = len - 1 ; i >= 0 ; i--)

{

ret.a[i] = (a[i] + down * (MAXN + 1)) / b;

down = a[i] + down * (MAXN + 1) - ret.a[i] * b;

}

ret.len = len;

while(ret.a[ret.len - 1] == 0 && ret.len > 1)

ret.len--;

return ret;

}

大数对一个int类型的变量进行取模运算

int BigNum::operator %(const int & b) const

{

int i,d=0;

for (i = len-1; i>=0; i--)

{

d = ((d * (MAXN+1))% b + a[i])% b;

}

return d;

}

大数的n次方运算

BigNum BigNum::operator^(const int & n) const

{

BigNum t,ret(1);

int i;

if(n<0)

exit(-1);

if(n==0)

return 1;

if(n==1)

return *this;

int m=n;

while(m>1)

{

t=*this;

for( i=1;i<<1<=m;i<<=1)

{

t=t*t;

}

m-=i;

ret=ret*t;

if(m==1)

ret=ret*(*this);

}

return ret;

}

大数和另一个大数的大小比较

bool BigNum::operator>(const BigNum & T) const

{

int ln;

if(len > T.len)

return true;

else if(len == T.len)

{

ln = len - 1;

while(a[ln] == T.a[ln] && ln >= 0)

ln--;

if(ln >= 0 && a[ln] > T.a[ln])

return true;

else

return false;

}

else

return false;

}

大数和一个int类型的变量的大小比较

bool BigNum::operator >(const int & t) const

{

BigNum b(t);

return *this>b;

}

输出大数

void BigNum::print()

{

int i;

cout << a[len - 1];

for(i = len - 2 ; i >= 0 ; i--)

{

cout.width(DLEN);

cout.fill('0');

cout << a[i];

}

cout << endl;

}

使用

BigNum a,b,c;

char s1[1000];

char s2[1000];

int main(){

scanf("%s",s1);

scanf("%s",s2);

a = s1;

b = s2;

c = a + b;

cout<

a = s1;

b = s2;

c = a - b;

cout<

 
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值