[蓝桥 2017]九宫幻方

文章讲述了如何通过编程解决一个关于三阶幻方的问题,给定一个被部分抹去数字的3x3矩阵,判断是否存在且仅有一个解,可以通过镜像和旋转操作还原标准幻方。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

九宫幻方

题目描述

小明最近在教邻居家的小朋友小学奥数,而最近正好讲述到了三阶幻方这个部分,三阶幻方指的是将 1~9 不重复的填入一个 3*3 的矩阵当中,使得每一行、每一列和每一条对角线的和都是相同的。

三阶幻方又被称作九宫格,在小学奥数里有一句非常有名的口诀:"二四为肩,六八为足,左三右七,戴九履一,五居其中",通过这样的一句口诀就能够非常完美的构造出一个九宫格来。

4 9 2

3 5 7

8 1 6

有意思的是,所有的三阶幻方,都可以通过这样一个九宫格进行若干镜像和旋转操作之后得到。现在小明准备将一个三阶幻方(不一定是上图中的那个)中的一些数抹掉,交给邻居家的小朋友来进行还原,并且希望她能够判断出究竟是不是只有一个解。

而你呢,也被小明交付了同样的任务,但是不同的是,你需要写一个程序。

输入描述

输入仅包含单组测试数据。

每组测试数据为一个 3*3 的矩阵,其中为 0 的部分表示被小明抹去的部分。

给出的矩阵至少能还原出一组可行的三阶幻方。

输出描述

如果仅能还原出一组可行的三阶幻方,则将其输出,否则输出"Too Many"(不包含引号)。

输入输出样例

示例

输入

0 7 2
0 5 0
0 3 0

输出

6 7 2
1 5 9
8 3 4

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

总通过次数: 1096  |  总提交次数: 1260  |  通过率: 87%

难度: 困难   标签: 2017, 暴力, 省赛, 搜索

代码分享:

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int p[10],a[5][5],b[5][5],ans[5][5];
int main()
{
  for(int i=1;i<=3;i++)
      for(int j=1;j<=3;j++)
          cin>>a[i][j];//读入样例矩阵

  for(int i=1;i<=9;i++)
      p[i]=i;

  int cnt=0;//统计九宫幻方的个数
  do{
    b[1][1]=p[1],b[1][2]=p[2],b[1][3]=p[3];
    b[2][1]=p[4],b[2][2]=p[5],b[2][3]=p[6];
    b[3][1]=p[7],b[3][2]=p[8],b[3][3]=p[9];
    //判断排列矩阵和样例矩阵是否匹配
    bool flag = true;//flag = ture表示匹配,flag = false表示不匹配
    for(int i=1;i<=3;i++){
      for(int j=1;j<=3;j++){
        if(!a[i][j]) continue;//只看非零部分
        if(a[i][j] != b[i][j]) flag = false;
      }
    }
    if(!flag) continue;//如果不匹配
    //判断排列矩阵是否是九宫幻方
    bool ok = true;//ok = ture表示排列矩阵是九宫幻方,ok = flase表示排列矩阵不是九宫幻方
    int sum = b[1][1] + b[2][2] + b[3][3];//取一条对角线
    if(sum !=b[1][3]+b[2][2]+b[3][1]) continue;//判断另一条对角线的和是否等于sum,不等于就跳过

    for(int i=1;i<=3;i++){
      int tmp1 = 0,tmp2 = 0;//tmp1表示行和,temp2表示列和
      for(int j=1;j<=3;j++){
        tmp1+=b[i][j];
        tmp2+=b[j][i];
      }
      if(tmp1 !=sum ||tmp2 !=sum)
      ok =false;//如果行的和或列的和不等于sum,则排列矩阵不是九宫幻方
    }
    if(!ok) continue;//如果不是九宫幻方,就跳过
    cnt++;//九宫幻方的个数+1
    if(cnt>=2)
    return cout<<"Too Many\n",0;//九宫幻方的个数》=2,直接输出Too Many,结束程序
    for(int i = 1;i<=3;i++)
      for(int j = 1;j <= 3;j++)
        ans[i][j] = b[i][j];//用ans记录下该九宫幻方
  }while(next_permutation(p + 1,p + 1 + 9));
  for(int i=1;i<=3;i++){
    for(int j=1;j<=3;j++){
      if(j==1)
      cout<<ans[i][j];
      else
      cout<<" "<<ans[i][j];
    }
    cout<<endl;
  }
  // 请在此输入您的代码
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鑫鑫向栄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值