ICPC本地赛题Computer Class:邻座编号差大于1的排列实现问题
Computer Class赛题代码分析
现有代码存在的问题
- 硬编码逻辑错误:3*3场景(len=9)的硬编码输出中出现了超出编号范围的
11,属于非法输出,直接不符合题目要求。 - 边界判断缺失:未处理单行/单列场景,比如11是合法场景(输出1即可),14合法、1*2非法等逻辑都没有覆盖,直接走通用排列逻辑会输出错误结果。
- 行列输出逻辑错误:题目定义是m行n列,每行n张课桌,但代码中换行判断使用
(i + 1) % n == 0,会导致最终输出的行列数颠倒,不符合输入要求。 - 无解场景判断错误:原代码判断n和m都小于4时就输出-1,会漏掉34、42等存在合法解的场景,同时没有覆盖2*2这种确实无解的小尺寸场景。
- 输出格式错误:输出-1时多了空格变成
- 1,且每个数字后多余的.和制表符不符合常规题目的输出要求。
可优化点
- 先明确无解场景,统一前置判断:
仅当满足以下任意条件时输出-1:
- 单行/单列且长度为2/3(即
min(n,m)==1 && 2<=max(n,m)<=3) - 尺寸为2*2
其余所有场景都存在合法解
- 去掉错误硬编码,统一使用奇偶分离排列策略:先按行优先顺序填充所有偶数,再填充所有奇数,该策略天然保证相邻数字奇偶性不同,差值必然大于1,时间复杂度为O(nm),完全满足5050规模的性能要求。
- 修正行列输出逻辑,严格按照输入的m行n列输出,输出格式仅保留数字和必要的空格、换行。
- 移除死循环逻辑,符合算法题单次输入输出的提交规范。
修正后参考C++实现
#include <iostream> #include <vector> using namespace std; int main() { int n, m; cin >> n >> m; int total = n * m; // 前置判断无解场景 bool impossible = false; if (min(n, m) == 1) { int len = max(n, m); if (len >=2 && len <=3) impossible = true; } else if (n == 2 && m == 2) { impossible = true; } if (impossible) { cout << -1 << endl; return 0; } // 生成排列:先偶后奇 vector<vector<int>> res(m, vector<int>(n)); int even = 2, odd = 1; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (even <= total) { res[i][j] = even; even += 2; } else { res[i][j] = odd; odd += 2; } } } // 输出结果 for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { cout << res[i][j] << " "; } cout << endl; } return 0; }
内容的提问来源于stack exchange,提问作者Enderg
相关产品推荐
相关产品推荐

