時間限制:1.0s 內存限制:256.0MB
問題描述
小明最近在教鄰居家的小朋友小學奧數,而最近正好講述到了三階幻方這個部分,三階幻方指的是將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
解題思路
把所有爲0的點記錄下來,然後一層層(一個數就是一層 )的依次進行搜索,填完後判斷。
AC代碼
#include <iostream>
#include <cstring>
using namespace std;
struct Point {
int x,y;
}p[11];
int mp[4][4],ans[4][4],tot;
bool book[10];
bool Judge()
{
int sum = mp[1][1]+mp[1][2]+mp[1][3];
int temp;
for(int i=2;i<=3;i++) {
temp = 0;
for(int j=1;j<=3;j++)
temp += mp[i][j];
if(temp != sum)
return false;
}
for(int j=1;j<=3;j++) {
temp = 0;
for(int i=1;i<=3;i++)
temp += mp[i][j];
if(temp != sum)
return false;
}
if(mp[1][1]+mp[2][2]+mp[3][3] != sum)
return false;
if(mp[1][3]+mp[2][2]+mp[3][1] != sum)
return false;
return true;
}
void dfs(int num,int k)
{
if(num == k) {
if(Judge()) {
tot++;
if(tot == 2)
return;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
ans[i][j] = mp[i][j];
}
}
for(int i=1;i<=9;i++) {
if(book[i])
continue;
book[i] = true;
mp[p[num].x][p[num].y] = i;
dfs(num+1,k);
if(tot == 2)
return;
book[i] = false;
}
}
int main()
{
memset(book,false,sizeof book);
int k=0;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++) {
cin >> mp[i][j];
if(mp[i][j] == 0) {
p[k].x = i;
p[k++].y = j;
}
else
book[mp[i][j]] = true;
}
tot = 0;
dfs(0,k);
if(tot == 2)
cout << "Too Many\n";
else {
for(int i=1;i<=3;i++) {
for(int j=1;j<=3;j++) {
cout << ans[i][j];
if(j!=3)
cout << " ";
}
cout << endl;
}
}
return 0;
}