题目链接:http://hihocoder.com/contest/hiho135/problem/1
题解:
一看是个3*3的幻方,直接上手暴力。
大体思路:
暴力枚举幻方中的 0 的数字,dfs 一遍进行 test,如果可以,计数器+1,记录幻方。到最后 test 计数器。如果 == 1,就输出幻方,否则输出 Too Many(注意:两个单词都大写! 没有叹号!【坑了我两次】)
代码:
#include <cstdio>
const int n = 3, fnl = 15; // fnl --> 洛书三阶幻方每行每列之和
int squ[n*n+5], vis[n*n+5], ans[n*n+5];
bool check() {
int temp = squ[1]+squ[2]+squ[3];
if(temp != fnl) return false;
for ( int i = 4; i <= n*n; i += 3 ) { // 横行
if(squ[i]+squ[i+1]+squ[i+2] != temp) return false;
}
for ( int i = 1; i <= n; i ++ ) { // 竖列
int tpot = 0;
for ( int j = 0; j < n; j ++ ) {
tpot += squ[n*j+i];
}
if(tpot != temp) return false;
}
if(squ[1]+squ[5]+squ[9] != temp || squ[3]+squ[5]+squ[7] != temp) return false; // 对角线
return true;
}
int cnt = 0;
void dfs(int pos) {
if( pos > n*n && check() ) {
cnt ++;
if(cnt == 1)
for ( int i = 1; i <= n*n; i ++ ){ ans[i] = squ[i]; }
return ;
}
if(squ[pos]) dfs(pos+1);
else {
for ( int i = 1; i <= n*n; i ++ ) {
if(vis[i]) continue;
vis[i] = 1;
squ[pos] = i;
dfs(pos+1);
squ[pos] = 0;
vis[i] = 0;
}
}
}
int main() {
// freopen("135A.in", "r", stdin);
for( int i = 1; i <= 9; i ++ ) {
scanf("%d", &squ[i]);
vis[squ[i]] = 1;
}
dfs(1);
if(cnt > 1) puts("Too Many");
else {
for ( int i = 1; i <= n*n; i ++ ) {
printf("%d ", ans[i]);
if(i%3 == 0) puts("");
}
}
return 0;
}