题目给了提示,3阶幻方都可由一个经过镜像和旋转得来。不过,即使不知道这一条信息,全部暴力搜索时间复杂度依旧不会超出上限,并且暴力搜索的方法更好写。
参考代码
cpp
#include <bits/stdc++.h>
using namespace std;
// 检查是否满足三阶幻方的求和要求
bool check(vector<int> &p) {
int sum = 15;
// 行
if (p[0] + p[1] + p[2] != sum) return false;
if (p[3] + p[4] + p[5] != sum) return false;
if (p[6] + p[7] + p[8] != sum) return false;
// 列
if (p[0] + p[3] + p[6] != sum) return false;
if (p[1] + p[4] + p[7] != sum) return false;
if (p[2] + p[5] + p[8] != sum) return false;
// 对角线
if (p[0] + p[4] + p[8] != sum) return false;
if (p[6] + p[4] + p[2] != sum) return false;
return true;
}
int main() {
// 加速 IO
ios::sync_with_stdio(false);
cin.tie(0);
vector<int> input(9);
for (int i = 0; i < 9; i++) {
cin >> input[i];
}
// next_permutation 必须从升序序列开始才能遍历所有排列
vector<int> p = {1, 2, 3, 4, 5, 6, 7, 8, 9};
vector<vector<int>> results;
do {
if (check(p)) {
bool match = true;
for (int i = 0; i < 9; i++) {
if (input[i] != 0 && p[i] != input[i]) {
match = false;
break; // 发现不匹配立刻跳出,提高效率
}
}
if (match) {
results.push_back(p);
}
}
} while (next_permutation(p.begin(), p.end())); // 注意这里的分号!
// 题目说“至少能还原出一组”,所以只需要判断是 1 个还是多个
if (results.size() == 1) {
for (int i = 0; i < 9; i++) {
cout << results[0][i] << (i % 3 == 2 ? "\n" : " ");
}
} else {
// 如果 results.size() > 1
cout << "Too Many" << endl;
}
return 0;
}