0%

20年三道编程大题

题库有些简单,换新的题来写一下,自从20年之后,专业课难度感觉直线飙升啊。

第一题-字符串中找出英文数组

image-20231011225540518

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include<stdio.h>
#include<string.h>

void fun(char str[], char *p) {
int len;
len = strlen(str);
char item;
int cishu = 0;
for (int i = 0; i < len; i++) {
if ((('a' <= str[i]) && ('z' >= str[i])) || (('A' <= str[i]) && ('Z' >= str[i]))) {
item = str[i];
for (int j = i; j < len-1; j++) {
str[j] = str[j + 1];
}
str[len - 1] = item;
i--;//避免有连续的字母,这样就可以不断检测这一位是否是字母
}
cishu++;
if (cishu >= len) {//避免无限循环
return;
}
}
}

int main() {
printf("请输入一串字符串:");
char ch[128] = "";
char* p;
p = ch;
scanf("%s", ch);
fun(ch, p);
printf("\n处理如下:%s", ch);
return 0;
}

image-20231011231316782

第二题-求数组列和

image-20231011232331406

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <string.h>
int fun(int arr[][3], int n);

int main()
{
//我们这里就求一个3行3列数组的第一列和最后一列之和。
int arr[3][3] = { {1,2,3},{7,8,2},{2,3,4} };
printf("%d", fun(arr, 3));
}

int fun(int arr[][3], int n) {//n为n行数组的意思
int sum = 0;
for (int i = 0; i < n; i++) {
//循环第一列
sum += arr[i][0];
}

for (int i = 0; i < n; i++) {
//循环最后一列
sum += arr[i][2];
}
return sum;
}

第三题-结构体指针

image-20231021194501769

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <stdio.h>
#include <string.h>

struct Student {
char name[20];
int english;
int math;
int politics;
int specialised;
int SUM = english + math + politics + specialised;
};

int fun(struct Student aa[], int (*p)(struct Student aa[])) {
//p指向fun2
return p(aa);;
}

int fun2(struct Student aa[]);

int main()
{

struct Student aa[4] = {
{"越江", 65, 85, 60, 110},
{"张三", 77, 100, 60, 60},
{"李四", 60, 60, 60, 60},
{"王五", 75, 75, 75, 75}
};
int max_index = fun(aa,fun2);
printf("获得最高分的是国服%s,分数为:%d", aa[max_index].name, aa[max_index].SUM);
}


int fun2(struct Student aa[]) {
int av_english, av_math, av_politcs, av_specialised;
char av_name[20];
int sum = 0;
int sum2 = 0;
int sum3 = 0;
int sum4 = 0;
for (int i = 0; i < 4; i++) {
sum += aa[i].english;
sum2 += aa[i].math;
sum3 += aa[i].politics;
sum4 += aa[i].specialised;
}
av_english = sum / 4;
av_math = sum2 / 4;
av_politcs = sum3 / 4;
av_specialised = sum4 / 4;
printf("平均成绩\n英语:%d\n数学:%d\n政治:%d\n专业课:%d\n", av_english, av_math, av_politcs, av_specialised);

int max_index = 0;//只记录一个最大分就可
for (int i = 0; i < 4; i++) {
if (aa[i].SUM > aa[max_index].SUM) {
max_index = i;
}
}

return max_index;
}

PKI(数字证书系统)

bilibili找了个课程,记录一下学习过程

散列函数

image-20231013201415718

散列函数的特点:固定大小,雪崩效应,单向,冲突避免

密钥算法

简单记录一下,

对称密钥算法

使用相同的密钥的算法进行加密和解密,优点:非常快,安全,紧凑。

非对称密钥算法

image-20231015184112596

缺点:加密速度非常慢,密文会非常长。

一般来说,都是对称加密和非对称机密同时使用,

image-20231015190332650

image-20231015190338867

数字签名

image-20231015190853472

证书加密是私钥,解密(校验)是公钥。
因为只有发送方存在私钥,所以证书具有不可否认性。
任何人都有公钥,来校验这个文件是否完整和是否源自发送方。

数字证书

image-20231015191809857

证书系统的目的就是给两端提供一次安全的公钥加密

image-20231015193250043

受信任的介绍,通过中间人b,使a和c建立受信任的联系。

证书授权颁发机构CA

image-20231015193426511

1
2
3
1.PKI  最高级的(类似zf,为了颁布证书所弄出来的所有东西)
2.CA 中间的(类似发证的机构,公安局之类的)
3.证书 (类似身份证)

步骤:

image-20231015193656625

1.首先客户需要得到ca的根证书,然后将客户自己的公钥提供给ca。

image-20231015193747827

2.证书服务器会把客户的个人信息和公钥,哈希加密之后得到的东西就叫签名。随后,将明文的个人信息,明文的公钥,明文的hash(通过CA的私钥做的),这个东西的集合就叫数字证书(下图)

image-20231015194232854

3.客户收到CA发送的消息之后,就可以通过CA的公钥对hash值进行校验,确定是CA发布的。这个时候就可以通过消息中的公钥得到对面客户的公钥。

证书申请的步骤

同步时间

时间是整个PKI系统的重中之重,必须要先确保参加PKI系统的设备和主机的时间同步,才能开始PKI的部署。

部署证书服务器

image-20231016182824907

客户端产生密钥

每一个实体在申请证书之前,需要预先产生RSA密钥对。

验证证书服务器

每一个实体需要获取证书服务器的根证书,里面包含证书服务器的公钥。获取了根证书后,乐意通过fingerprint离线验证证书服务器。

申请个人证书

审核并签名证书

颁发数字证书

交换公钥

证书的申请与吊销

image-20231016183313907

三个经典的申请方式。

申请

image-20231016183335825

吊销

image-20231016184107006

c语言之螺旋数组

前言

我看到很多回忆题目都写了螺旋数组,20年之前是没有的,所以我们现在学习一下c语言中的螺旋数组,分为四种。

按方向分,分为顺时针和逆时针。按起始顺序分,分为中间开始(太难了,以前的也没考过从中间开始的)和开头开始。排列组合后分为四种。

我一定要成功!!考研真的太痛苦了,不想来第二遍了,整个人的生活都停下来了,就为了这么个东西,太太太太太太太烦人了,现在越来越想躺平了,要是以后生活都这么痛苦的话我都不知道怎么活😋。

螺旋数组的编写

开始之顺时针

image-20231009182256595

用这种方式的螺旋数组,在看了思路之后,我会尝试自己写出螺旋数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <stdio.h>



int main(){
int arr[5][5];//定义一个5x5的数组
int a=0, b=4,c=4,d=0;//定义了4个边界
//其中a为上边界,b为右边界,c为下边界,d为左边界
int item = 1;//定义一个元素,用来给数组赋值
while (a<=c&&d<=b) {
//上行
for (int i = d; i <= b; i++) {
arr[a][i] = item;
item++;
}
a++;//上边界缩小

//右列
for (int i = a; i <= c; i++) {
arr[i][b] = item;
item++;
}
b--;//右边界缩小

//下行
for (int i = b; i >= d; i--) {
arr[c][i] = item;
item++;
}
c--;//下边界缩小

//左列
for (int i = c; i >= a; i--) {
arr[i][d] = item;
item++;
}
d++;//左边界缩小
}

//输出数组
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
printf("%3d", arr[i][j]);
}
printf("\n");
}

return 0;
}

image-20231009185741343

w芜湖,其方法就是,不断收缩边界,达到边界的时候转为下一个边界即可。

开始之逆时针

国服逆时针!

image-20231009190321828

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h>



int main(){
int arr[5][5];//定义一个5x5的数组
int shang = 0, zuo = 0, you = 4, xia = 4;//定义国服边界
int item = 1;//定义一个元素,用来给数组赋值
while (shang <= xia && zuo <= you) {//国服条件
//左列
for (int i = shang; i <= xia; i++) {
arr[i][zuo] = item;
item++;
}
zuo++;

//下行
for (int i = zuo; i <= you; i++) {
arr[xia][i] = item;
item++;
}
xia--;

//右列
for (int i = xia; i >= shang; i--) {
arr[i][you] = item;
item++;
}
you--;

//上行
for (int i = you; i >= zuo; i--) {
arr[shang][i] = item;
item++;
}
shang++;
}
//输出数组
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
printf("%3d", arr[i][j]);
}
printf("\n");
}

return 0;
}

image-20231009191150189

我还专门改成偶数了,这个代码同样是有用的。

image-20231009192033123