73.稀疏矩阵
题目描述
明明的问题可以归结为:试编程将一个稀疏矩阵a转换成只存放非零元素的矩阵b,即找出每个不是0的元素,按从左到右从上到下的顺序,输出其所在的行和列以及它的值。
代码
cpp
#include <iostream>
using namespace std;
int main() {
int m, n;
bool isFirst = true; // 用于标记是否是第一组数据
// 循环读取每一组的行数 m 和列数 n
while (cin >> m >> n) {
// 如果不是第一组数据,先输出一个空行作为分隔
if (!isFirst) {
cout << endl;
}
// 处理完第一组后,标记置为 false
isFirst = false;
// 遍历矩阵
for (int i = 0; i < m; ++i) { // 行循环
for (int j = 0; j < n; ++j) { // 列循环
int val;
cin >> val; // 读取当前位置的数值
if (val != 0) {
// 题目要求下标从1开始,所以行和列都要 +1
cout << (i + 1) << " " << (j + 1) << " " << val << endl;
}
}
}
}
return 0;
}
总结
使用双重循环遍历矩阵(或者直接在读入时处理)。由于输入顺序本身就是"从上到下,从左到右",不需要存储整个矩阵,只需要读到一个非零数,就立即按照 i+1 (行), j+1 (列), val (值) 的格式输出即可。
74.矩阵转换
题目描述
明明是一个很聪明的孩子,学什么东西都很快。但是他也有个缺点,就是不愿意做重复的劳动,往往学会一样东西以后,就不太愿意再去碰它。有一天,明明在数学课上学了矩阵的转换,即有一个r×r的矩阵,把矩阵中的数以左上到右下的对角线的方式进行交换,然后形成一个新的矩阵。
例如:有个3×3的矩阵如下:
1 2 3
4 5 6
7 8 9
通过以左上到右下的对角线交换后,形成了一个新的矩阵:
1 4 7
2 5 8
3 6 9
明明很快就学会了,然后自己动手做了几个类似的转换。但是,课后老师布置了很多矩阵转换的作业,让同学回家练习,这就使明明很厌烦了,觉得自己已经学会了,就没有再练习的必要了。于是明明就请你帮个忙,帮他写一个程序,来计算矩阵的交换,帮他完成老师布置的作业。
明明的问题可以归结为:有一个r×r的矩阵,把矩阵中的数以左上到右下的对角线的方式进行转换,然后输出转换后的矩阵。
代码
cpp
#include <iostream>
#include <vector>
using namespace std;
int main() {
int r;
bool isFirst = true; // 标记是否是第一组数据,用于控制空行
while (cin >> r) {
// 如果不是第一组数据,输出一个空行与上一组隔开
if (!isFirst) {
cout << endl;
}
isFirst = false; // 处理完第一组后,标记设为 false
int matrix[10][10];
for (int i = 0; i < r; ++i) {
for (int j = 0; j < r; ++j) {
cin >> matrix[i][j];
}
}
// 反过来,外层循环遍历 j (原矩阵的列号),内层循环遍历 i (原矩阵的行号)
for (int j = 0; j < r; ++j) {
for (int i = 0; i < r; ++i) {
// 输出 matrix[i][j] 即按列读取
cout << matrix[i][j];
// 控制行末空格:如果是该行的最后一个数,不要输空格
if (i < r - 1) {
cout << " ";
}
}
cout << endl;
}
}
return 0;
}
总结
输出对称矩阵,把内外层循环换一下就行(先行后列→先列后行),然后注意最后一个数后面没有空格。
75.魔方阵
题目描述
在一次数学课上,明明的老师讲了一种非常有趣的方阵,称之为三阶魔方阵。
它是一个三行三列,由1、2、3、......8、9,九个数字共同构成,且它每行、每列、两对角线之和均相等,于是一个合法的三阶魔方阵就形成了以下的方阵:
8 1 6
3 5 7
4 9 2
富有钻研精神的明明回家后,马上就对三阶魔方阵进行研究。
他总结出了5条n阶魔方阵的规律(n为奇数),如下:
(1) 将"1"放在第一行(最上面一行)中间一列;
(2) 从"2"开始直到n*n为止各数依次按下列规则存放:每一个数存放的行的行数比前一个数的行数减1,每一个数存放的列的列数比前一个数的列数加1,即前一个数的右上方。
(3) 如果上一数的行数为1,则下一个数的行数为n(指最下面一行);
(4) 当上一个数的列数为n时,下一个数的列数应为1(指最左一列);
(5) 如果按上面规则确定的位置上已有数,或上一个数是第一行第n列时,则把下一个数放在上一个数的下面。
有了以上的方法,明明就可以轻易地构造出任意的n阶魔方阵。
例如构造3阶魔方阵的过程如下:
先将1放在第一行的中间一列:
放1:(参考规则1)
* 1 *
* * *
* * *
放2:(参考规则3)
* 1 *
* * *
* * 2
放3:(参考规则4)
* 1 *
3 * *
* * 2
放4:(参考规则5)
* 1 *
3 * *
4 * 2
放5:(参考规则2)
* 1 *
3 5 *
4 * 2
放6:(参考规则2)
* 1 6
3 5 *
4 * 2
放7:(参考规则5)
* 1 6
3 5 7
4 * 2
放8:(参考规则4)
8 1 6
3 5 7
4 * 2
放9:(参考规则3)
8 1 6
3 5 7
4 9 2
但是随着n的不断增大,构建一个n阶魔方阵所花的精力就越多。于是明明就请你帮忙,帮助他用程序来构建n阶魔方阵。
明明的问题可以归结为:给你一个阶数n,请你按照题目中描述的方法,构造出n阶魔方阵。
代码
cpp
#include <iostream>
#include <vector>
#include <cstring> //用于 memset
using namespace std;
int main() {
int n;
bool isFirst = true; // 用于控制测试用例之间的空行
// 循环读取输入 n
while (cin >> n) {
// 如果不是第一组数据,先输出一个空行
if (!isFirst) {
cout << endl;
}
isFirst = false;
int matrix[20][20];
// 清零,判断格子是否"已有数" (即值是否不为0)
memset(matrix, 0, sizeof(matrix));
// 放置数字 1 (规则1: 第一行中间)
int row = 0;
int col = n / 2;
matrix[row][col] = 1;
// 循环放置剩余的数字 (从 2 到 n*n)
for (int num = 2; num <= n * n; ++num) {
// 先计算"右上方"的坐标
int next_row = row - 1;
int next_col = col + 1;
// 处理越界 (规则3 & 规则4)
if (next_row < 0) next_row = n - 1; // 上越界 -> 去最后一行
if (next_col > n - 1) next_col = 0; // 右越界 -> 去第一列
// 检查特殊情况 (规则5)
if (matrix[next_row][next_col] != 0) {
// 如果冲突,放在上一个数的下面
row = row + 1
} else {
// 如果没冲突,就确认移动到右上方
row = next_row;
col = next_col;
}
// 填入数字
matrix[row][col] = num;
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
cout << matrix[i][j];
// 行末不要多余空格
if (j < n - 1) {
cout << " ";
}
}
cout << endl;
}
}
return 0;
}
总结
起点 :数字 1 永远放在第一行的正中间。
正常移动 :下一个数字应该放在右上方(行减1,列加1)。
越界处理:
- 如果行 超出了最上面(变成-1),就跳到最后一行。
- 如果列 超出了最右边(变成N),就跳到第一列。
特殊情况(冲突处理):
- 如果右上方 的位置已经填过数字了 ,或者当前位置是最右上角 (比如 3×33\times33×3 中的第1行第3列),那么下一个数字不要去右上方,而是直接填在当前数字的正下方。
贴合题目逻辑在右上角写法时用了if-else
// 处理越界 (规则3 & 规则4)
if (next_row < 0) next_row = n - 1; // 上越界 -> 去最后一行
if (next_col > n - 1) next_col = 0; // 右越界 -> 去第一列
简单点可以写成
(row - 1 + n) % n
翻译
协同技术发挥着辅助作用。例如,生物识别技术可以广泛应用于个性化人类、机器和物体之间的交互。人工智能、计算机视觉、机器人技术和远程呈现可以让我们的未来生活更加自动化。
作为一种新兴技术,物联网将变得更加成熟和复杂。图 12C-1 展示了可能受益于物联网的主要技术进步和关键应用。例如,现在的供应链比以往得到了更好的支持。
垂直市场应用可能代表下一波进步的浪潮。随着我们迈向 2020 年,无处不在的定位有望成为现实。除此之外,物理物联网可能会在全球范围内落实到位。这些进步将显著提升人类能力、社会成果、国家生产力和生活质量。
biometrics ------ 生物识别技术
sophisticated ------ 复杂的 / 精密的
supply chains ------ 供应链
vertical market ------ 垂直市场
societal ------ 社会的
productivity ------ 生产力
harvesting ------ 收集 / 采集(图中表格出现 Energy harvesting 能量采集)
spectrum ------ 频谱(图中图表出现 available spectrum 可用频谱)
diffusion ------ 扩散 / 普及(图中图表出现 diffusion into...)
emerging technology ------ 新兴技术
mature ------ 成熟的
Vertical ------ 垂直的(文中指"纵向的"或"垂直领域的",如 Vertical market 垂直市场)
