考点
-
排序
- 冒泡排序 O(n^2)
- 选择排序 O(n^2)
- (插入排序)
-
分离每一位
- 正序
- 字符串
- 栈(递归)
- 逆序
- 正序
-
哈希(hash) → 用值直接作为下标
-
数组的基本操作
- 插入和删除
- 逆序(移位)
-
日期处理问题
-
7 - 19田忌赛马 (双指针)
-
二维数组 → 矩阵
- 矩阵转置
- 判断对称矩阵
- 矩阵运算
- 矩阵移位
-
杨辉三角
二维数组
二维数组 → 很多一维数组
int q[n][m];
n个大小为m的一维数组组成的s
123
456
789
for(int i = 0; i < n; i++) //行
{
for(int j = 0; j < m; j++) //列
{
scanf("%d", &q[i][j]);
printf("%d", q[i][j]);
}
}
矩阵的加法
- 条件: 两个矩阵的行和列相同
a * b
m * n
6 5 1
2 1 4
7 8 9
6 1 3
13 13 10
8 2 7
a = m, b = n
int p[150][150];
int q[150][150];
int ans[150][150];
for(int i = 0; i < a; i++)
{
for(int j = 0; j < b; j++)
{
scanf("%d", &p[i][j]);
}
}
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
scanf("%d", &q[i][j]);
}
}
for(int i = 0; i < n; i ++)
{
for(int j = 0; j < m; j++)
{
ans[i][j] = p[i][j] + q[i][j];
}
}
for(int i = 0; i < n; i ++)
{
for(int j = 0; j < m; j++)
{
printf("%d ", ans[i][j]);
}
}
矩阵的乘法
- 要求第一个矩阵的列 = 第二个矩阵的行, 最终答案为第一个矩阵的行 * 第二个矩阵的列
a * b
m * n
b = m
第一个矩阵的列 = 第二个矩阵的行
结果为a * n的矩阵
3 * 2 2 * 3
1 2 1 2 3
1 3 3 4 5
1 4
第一个矩阵的行 * 第二个矩阵的列
```cpp
int p[150][150];
int q[150][150];
for(int i = 0; i < a; i++) //a * b
{
for(int j = 0; j < n; j++) // m * n
{
//计算ans[i][j]
for(int k = 0; k < b; k++) // k < m也可以
{
ans[i][j] += p[i][k] * q[k][j];
}
}
}
for(int i = 0; i < a; i++)
{
for(int j = 0; j < n; j++)
{
printf("%d ", ans[i][j]);
}
printf("\n");
}
//计算结果矩阵的第(i, j)个元素的时候, 需要用第一个矩阵的第i行的所有元素分别与第二个矩阵的第j列的所有元素分别相乘再相加
x1 = 1 * 1 + 2 * 3
x2 = 1 * 2 + 2 * 4
x3 = 1 * 3 + 2 * 5
x4 = 1 * 1 + 3 * 3
x5 = 1 * 2 + 3 * 4
x6 = 1 * 3 + 3 * 5
x7 = 1 * 1 + 4 * 3
x8 = 1 * 2 + 4 * 4
x9 = 1 * 3 + 4 * 5
x1 x2 x3
x4 x5 x6
x7 x8 x9
#include <stdio.h>
int p[150][150];
int q[150][150];
int ans[150][150];
int main()
{
int a, b, m, n;
scanf("%d %d %d %d", &a, &b, &m, &n);
for(int i = 0; i < a; i++)
{
for(int j = 0; j < b; j++)
{
scanf("%d", &p[i][j]);
}
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
scanf("%d", &q[i][j]);
}
}
for(int i = 0; i < a; i++) //a * b
{
for(int j = 0; j < n; j++) // m * n
{
//计算ans[i][j]
for(int k = 0; k < b; k++) // k < m也可以
{
ans[i][j] += p[i][k] * q[k][j];
}
// printf("%d ", ans[i][j]);
}
printf("\n");
}
for(int i = 0; i < a; i++)
{
for(int j = 0; j < n; j++)
{
printf("%d ", ans[i][j]);
}
printf("\n");
}
return 0;
}
求对角线元素之和
m * m
int a[150][150];
int sum = 0;
for(int i = 0; i < m; i++)
{
sum += a[i][i];
}
7-2 求矩阵各行元素之和
for(int i = 0; i < n; i++)
{
int sum = 0;
for(int j = 0; j < m; j++)
{
sum += q[i][j];
}
printf("%d\n", sum);
}
对称矩阵
- 对称矩阵 → 关于主对角线对称, 必须行和列相同
a[i][j] 是否== a[j][i]
#include <stdio.h>
int q[50][50];
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
if(n == 0) break;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
scanf("%d", &q[i][j]);
}
}
int f = 1;//用来标记是否是对称矩阵
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
if(q[i][j] != q[j][i])
{
f = 0;
break;
}
}
if(f == 0) break;
}
if(f == 0)
printf("No.\n");
else
printf("Yes.\n");
}
return 0;
}
杨辉三角
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
0 0 0 0 0 0 0
0 1 0 0 0 0 0
0 1 1 0 0 0 0
0 1 2 1 0 0 0
0 1 3 3 1 0 0
0 1 4 6 4 1 0
#include <stdio.h>
int q[50][50];
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
if(n == 0) break;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= i; j++)
{
if(j == 1 || j == i)
{
q[i][j] = 1;
}
else q[i][j] = q[i - 1][j] + q[i - 1][j - 1];
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
if (j == 1)
printf("%d", q[i][j]);
else
printf(" %d", q[i][j]);
}
printf("\n");
}
printf("\n");
}
return 0;
}
7-5 sdut-C语言实验- 鞍点计算
#include <stdio.h>
int q[20][20];
int main()
{
int m, n;
scanf("%d %d", &m, &n);
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
scanf("%d", &q[i][j]);
}
}
int f = 1;
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
//拿到(i, j)点,i和j就固定了,
//假设当前(i, j)为鞍点, 更新ans_x, ans_y, ans, f
f = 1;
int ans_x = i, ans_y = j;
int ans = q[i][j];
//是否在该行上最大 (行i固定, 遍历列)
for(int k = 0; k < n; k++)
{
if(q[i][k] > q[i][j])
{
f = 0;
break;
}
}
// 是否在该列最小 (列j固定, 遍历列)
for(int k = 0; k < m; k++)
{
if(q[k][j] < q[i][j])
{
f = 0;
break;
}
}
if(f == 1)
{
printf("Array[%d][%d]=%d\n", ans_x, ans_y, ans);
return 0;
}
}
}
if(f == 0) //如果n * m个点都比较完了而且都不是鞍点, 说明没有鞍点
printf("None\n");
return 0;
}
矩阵移位
矩阵旋转
矩阵转置
q[i][j] = q[j][i]
定义一个新的数组ans, ans[j][i] = q[i][j]
#include <stdio.h>
int q[150][150];
int ans[150][150];
int main()
{
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
scanf("%d", &q[i][j]);
ans[j][i] = q[i][j];
}
}
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
if(j == 0) printf("%d", ans[i][j]);
else printf(" %d", ans[i][j]);
}
printf("\n");
}
return 0;
}
m = m % n
假设下标为i, 移动m次后成为了新的第一个数
最后一个数下标为n - 1
i ~ n - 1 一共有n - 1 - i + 1 = n - i个数, i到n-1需要移动 n - i - 1次
最后一个元素(下标n - 1) → 第一个元素还需要在移动一次
n - i - 1 + 1次 = m
→ i = n - m(必须保证这个i是正的)
[n - m, n - 1]