题目描述
小明最近在教邻居家的小朋友小学奥数,而最近正好讲述到了三阶幻方这个部分,三阶幻方指的是将1~9不重复的填入一个3*3的矩阵当中,使得每一行、每一列和每一条对角线的和都是相同的。
三阶幻方又被称作九宫格,在小学奥数里有一句非常有名的口诀:“二四为肩,六八为足,左三右七,戴九履一,五居其中”,通过这样的一句口诀就能够非常完美的构造出一个九宫格来。
4 9 2
3 5 7
8 1 6
有意思的是,所有的三阶幻方,都可以通过这样一个九宫格进行若干镜像和旋转操作之后得到。现在小明准备将一个三阶幻方(不一定是上图中的那个)中的一些数抹掉,交给邻居家的小朋友来进行还原,并且希望她能够判断出究竟是不是只有一个解。
而你呢,也被小明交付了同样的任务,但是不同的是,你需要写一个程序~
输入
输入仅包含单组测试数据。
每组测试数据为一个3*3的矩阵,其中为0的部分表示被小明抹去的部分。
对于100%的数据,满足给出的矩阵至少能还原出一组可行的三阶幻方。
输出
如果仅能还原出一组可行的三阶幻方,则将其输出,否则输出“Too Many”(不包含引号)。
样例输入
0 7 2
0 5 0
0 3 0
样例输出
6 7 2
1 5 9
8 3 4
提示
笨笨有话说:
我最喜欢这类题目了。既然九宫幻方一共也没有多少,我就不辞辛劳地一个一个写出来好了。
也不能太过分,好歹用个数组。
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
vector<int> v,pos;
vector<int> a(10,0),ans(10,0);
int vis[15];
int res = 0;
bool check(){
for(int i = 0;i < pos.size();i ++) a[pos[i]] = v[i];
int t = a[1] + a[2] + a[3];
if(t == a[4]+a[5]+a[6] && t == a[7]+a[8]+a[9] && t == a[1]+a[4]+a[7]&& t == a[2]+a[5]+a[8]&& t == a[3]+a[6]+a[9]&& t == a[1]+a[5]+a[9]&& t == a[3]+a[5]+a[7]){
for(int i = 1;i <= 9;i ++) ans[i] = a[i];
++ res;
for(int i = 0;i < pos.size();i ++) a[pos[i]] = 0;
return true;
}
else{
for(int i = 0;i < pos.size();i ++) a[pos[i]] = 0;
return false;
}
}
int main()
{
for(int i = 1;i <= 9;i ++){
cin>>a[i];
if(a[i] == 0){
pos.push_back(i); //该填入值的位置集合
}
}
for(int i = 1;i <= 9;i ++) vis[a[i]] = 1;
for(int i = 1;i <= 9;i ++){
if(vis[i] == 0){
v.push_back(i); //需要填入的值集合
}
}
do{
if(check()){
if(res == 2){
cout<<"Too Many"<<endl;
return 0;
}
}
}while(next_permutation(v.begin(),v.end()));
for(int i = 1;i <= 9;i ++){
cout<<ans[i];
if(i % 3 == 0) cout<<endl;
else cout<<" ";
}
return 0;
}
JAVA解法:
import java.util.*;
public class Main {
static int ans = 0;
static int [] tmp = new int [10];
static int [] vis = new int [10];
static int [] used = new int [10];
static ArrayList<Integer> list = new ArrayList<>();
static ArrayList<Integer> list_idx = new ArrayList<>();
static ArrayList<Integer> list_num = new ArrayList<>();
static ArrayList<Integer> res = new ArrayList();
static boolean check() {
for(int i = 0;i < list_idx.size();i ++) {
list.set(list_idx.get(i), tmp[i]);
}
int t = list.get(0) + list.get(1) + list.get(2);
if( list.get(3) + list.get(4) + list.get(5) == t &&
list.get(6) + list.get(7) + list.get(8) == t &&
list.get(0) + list.get(3) + list.get(6) == t &&
list.get(1) + list.get(4) + list.get(7) == t &&
list.get(2) + list.get(5) + list.get(8) == t &&
list.get(0) + list.get(4) + list.get(8) == t &&
list.get(2) + list.get(4) + list.get(6) == t
) {
return true;
}
return false;
}
static void dfs(int idx,int n) {
if(idx == n) {
if(check()) {
ans ++;
res.addAll(list);
}
return;
}
for(int i = 0;i < list_num.size();i ++) {
if(used[list_num.get(i)] == 0) {
tmp[idx] = list_num.get(i);
used[list_num.get(i)] = 1;
dfs(idx+1,n);
used[list_num.get(i)] = 0;
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
for(int i = 1;i <= 9;i ++) {
int num = sc.nextInt();
list.add(num);
vis[num] = 1;
if(num == 0) {
list_idx.add(i-1);
}
}
for(int i = 1;i <= 9;i ++) {
if(vis[i] == 0) {
list_num.add(i);
}
}
dfs(0,list_num.size());
if(ans >= 2) {
System.out.println("Too Many");
}else {
for(int i = 0;i < 9;i ++) {
System.out.print(res.get(i));
if((i+1)%3==0) System.out.println();
else System.out.print(" ");
}
}
}
}