Skip to content

link

题目给了提示,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;
}