C/C++ 作业笔记

环文加密

题目

题目分析

通过if语句判断输入的字符是否为字母,只对字母进行加密,其他字符不加密。

解题思路

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
#include <stdio.h>
#include <string.h>
int main()
{
int key;
char s[100000]; //关键问题 如果字符串过长会导致栈溢出尽可能使用较大的数组
scanf("%d", &key);
getchar();
fgets(s, 100000, stdin); // 读取输入字符串
key = key % 26;
for (int i = 0; i <strlen(s); i++)
{
if ((s[i] >= 'a' && s[i] <= 'z'))
{
if (97 <= s[i] + key && s[i] + key <= 122)
{
s[i] = s[i] + key;
}
else if (97 > s[i] + key)
{
s[i] = s[i] + key + 26;
}
else if (122 < s[i] + key)
{
s[i] = s[i] + key - 26;
}
}
else if (s[i] >= 'A' && s[i] <= 'Z')
{
if (65 <= s[i] + key && s[i] + key <= 90)
{
s[i] = s[i] + key;
}
else if (65 > s[i] + key)
{
s[i] = s[i] + key + 26;
}
else if (90 < s[i] + key)
{
s[i] = s[i] + key - 26;
}
}
else
{
continue;
}
}

printf("%s", s);

return 0;
}

错误点

  • 字符串过长会导致栈溢出,应该使用较大的数组。
  • 大小写字母范围并不一致,应该分开处理。
  • 加密后字符可能超出范围,按照环文加密的规则,应该对超出范围的字符进行处理。

验证哥德巴赫猜想

解题思路

  • 通过题目我们要寻找最小的值,所以我们从最小的质数开始尝试,只要n - a的值b也是质数,那么就完成题目.
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
#include <stdio.h>

// 检查素数,返回1表示素数,0表示非素数
int is_prime(long long n)
{
if (n < 2)
{
return 0;
}
for (long long k = 2; k * k <= n; k++)
{
if (n % k == 0)
{
return 0;
}
}
return 1;
}

int main()
{
long long n = 0;
long long shu1 = 0, shu2 = 0;

// 输入n
scanf("%lld", &n);

for (long long i = 2; i <= n / 2; i++) // 从2到n/2遍历
{
if (is_prime(i))
{
shu1 = i;
shu2 = n - shu1;

// 检查剩余部分是否是素数
if (is_prime(shu2))
{
printf("%lld = %lld + %lld\n",n,shu1, shu2);
return 0;
}
}
}

return 0;
}

错误点

  • for (long long k = 2; k * k <= n; k++) // 遍历从2到√n k*k <= n
    这是因为当我们判断一个数 n 是否为素数时,
    如果 n 可以被某个数 k 整除,那么 n 必定有一个因子在 2 到 √n 之间。具体来说,如果 n 有一个大于 √n 的因子 k,那么对应的另一个因子 n/k 必定会小于 √n。
  • i <= n/2 也是同理,因为两个数的和等于 n,其中一个数不可能大于 n/2。

其他题目代码参考

7-1 求组合数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
double fact(double n)
{
double s=1;
for (int i = 1;i <= n;i++)
{
s = s * i;
}
return s;
}
int main()
{
int n, m;
scanf("%d %d",&m, &n);
double result = fact(n) / (fact(m) * fact(n-m));
printf("result = %.0f", result);
return 0;
}

7-4 求两个整数的最大公约数和最小公倍数

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
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

// 函数:求最大公约数
long long gcd(long long a, long long b)
{
while (b != 0)
{
long long temp = b;
b = a % b;
a = temp;
}
return a;
}

// 函数:根据最大公约数求最小公倍数
long long lcm(long long a, long long b)
{
return (a * b) / gcd(a, b);
}

int main()
{
long long A, B;

// 输入两个整数A和B
scanf("%lld %lld", &A, &B);

// 求最大公约数和最小公倍数
long long large_n = gcd(A, B);
long long least_n = lcm(A, B);

// 输出结果
printf("large_n=%lld,least_n=%lld\n", large_n, least_n);

return 0;
}