欢乐赛#54 T5 题解 100% AC
2025-08-25 17:59:53
发布于:江苏
13阅读
0回复
0点赞
#include <bits/stdc++.h>
using namespace std;
int mp[110][110]; // 定义二维数组存储方阵数据(预留+10防止越界)
int main() {
int n, m;
cin >> n >> m; // 输入行列数
// 读取原始方阵数据
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
cin >> mp[i][j];
// 列处理(每列代表一个班级)
for(int j = 1; j <= m; j++) {
vector<int> c; // 临时存储非零身高数据
// 收集当前列非零数据(过滤空位)
for(int i = 1; i <= n; i++)
if(mp[i][j] != 0) c.push_back(mp[i][j]);
sort(c.begin(), c.end()); // 升序排序($O(k\log k)$,k为该列人数)
// 重新填充当前列(保持原有非零位置结构)
int x = 0;
for(int i = 1; i <= n; i++)
if(mp[i][j] != 0) mp[i][j] = c[x++];
}
// 输出格式化结果
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++)
cout << setw(4) << mp[i][j]; // 固定4字符宽度输出
cout << endl;
}
return 0;
}
算法核心解析
- 列优先处理:将每列视为独立班级,满足题目"每列一个班"的要求
- 零值保留机制:
- 用
vector
过滤存储非零值(if(mp[i][j]!=0)
) - 排序后按原非零位置回填(保持空缺位置不变)
- 用
- 时间复杂度:,其中主要开销来自每列的排序操作
关键步骤说明
-
数据读取阶段:
- 使用双重循环存储矩阵
- 行列索引从1开始(符合题目描述习惯)
-
排序处理阶段:
- 对每列单独建立临时数组
c
存储有效身高 sort()
默认升序排列,满足"前低后高"要求- 回填时通过
x
指针确保有序数据覆盖原非零位
- 对每列单独建立临时数组
-
输出格式化:
setw(4)
保证输出对齐(包括数字和零值空格)- 严格保持原始矩阵的行列结构
示例演算
以样例输入为例:
6 4
186 188 163 142
139 141 151 0
...(略)...
处理第1列时:
- 收集非零值
[186, 139, 142, 169, 200]
- 排序得
[139, 142, 169, 186, 200]
- 按原非零位置回填,得到输出首列
[139, 142, 169, 186, 200, 0]
该实现完美满足题目所有要求:
- 保持列结构不变
- 正确处理空位(零值)
- 输出格式严格对齐
- 在给定数据范围内高效运行
这里空空如也
有帮助,赞一个