hiho 1268 九宫 搜索 模拟

来源:互联网 发布:多目标优化 百度百科 编辑:程序博客网 时间:2024/06/06 15:39

题目

题目链接:http://hihocoder.com/problemset/problem/1268

题目来源:hiho上的比赛

简要题意:给定3×3矩阵,一些空缺,问是否能构成唯一幻方。

题解

题意比较明白,然后问题比较基础。

幻方的定义就是横纵,对角线和都相等,由于和为45所以每条都是15

一共9个格子,然后每个格子去放入剩下的数字。

枚举的次数是9!每次就是去做和然后判断。

枚举的过程可以利用dfs回溯来做,代码量较长,适合练手。

为了给某同学看做了注释。

代码

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#include <stack>#include <queue>#include <string>#include <vector>#include <set>#include <map>#define fi first#define se secondusing namespace std;typedef long long LL;typedef pair<int,int> PII;// head// 给定的数组int a[3][3];// 临时使用的数组int temp[3][3];// 数字访问的情况bool vis[10];// 可以放入数字的位置vector<PII> b;// b每个位置上放的数int path[10];// 输出的结果int res[10];// 存在解bool ok = false;// 有多个解bool many = false;bool judge() {    // 把当前的数放到临时的数组里    for (int i = 0; i < b.size(); i++) {        temp[b[i].fi][b[i].se] = path[i];    }    // 判断横和纵的和是否为15    for (int i = 0; i < 3; i++) {        int sumc = 0, sumr = 0;        for (int j = 0; j < 3; j++) {            sumc += temp[i][j];            sumr += temp[j][i];        }        if (sumr != 15 || sumc != 15) return false;    }    // 判断对角线是否为15    int sum1 = 0, sum2 = 0;    for (int i = 0; i < 3; i++) {        sum1 += temp[i][i];        sum2 += temp[2-i][i];    }    return sum1 == 15 && sum2 == 15;}void dfs(int pos) {    // 全部放完了开始检查    if (pos == b.size()) {        bool ans = judge();        // 不合法就结束        if (!ans) return;        // 合法根据ok的情况去进行更新        if (ok) {            many = true;        } else {            ok = true;            memcpy(res, path, sizeof res);        }        return;    }    for (int i = 1; i <= 9 && !many; i++) {        // 用过的数字不用        if (vis[i]) continue;        // 更新放的数还有数使用的情况        path[pos] = i;        vis[i] = true;        dfs(pos+1);        // 结束,进行下次        vis[i] = false;    }}int main() {    for (int i = 0; i < 3; i++) {        for (int j = 0; j < 3; j++) {            scanf("%d", a[i]+j);            // 为0就是可以放数字的,否则就更新使用情况            if (!a[i][j]) {                b.push_back(make_pair(i, j));            } else {                vis[a[i][j]] = true;            }        }    }    memcpy(temp, a, sizeof temp);    dfs(0);    // 根据情况输出    if (many) {        puts("Too Many");    } else if (ok) {        for (int i = 0; i < b.size(); i++) {            a[b[i].fi][b[i].se] = res[i];        }        for (int i = 0; i < 3; i++) {            for (int j = 0; j < 3; j++) {                printf("%d%c", a[i][j], j==2 ? '\n' : ' ');            }        }    }    return 0;}
0 0
原创粉丝点击