试题 历届试题 九宫幻方(dfs)

 
问题描述
3*3矩阵,1-9个数字每个数字只能使用一次,要求行列对角线的和都相等,如果仅能还原出一组可行的三阶幻方,则将其输出,否则输出“Too Many”(不包含引号)。
样例输入
0 7 2
0 5 0
0 3 0
样例输出
6 7 2
1 5 9
8 3 4
思路

这个题目比较简单,基本的深搜,标记用过的数字,回溯时取消。

卡的地方在于我一开始写dfs在里面用了两个循环遍历所有位置,再去找空的位置去填,这样导致了多个重复的结果,dfs的题目还是要多练才行。

正解是枚举每一个位置pos,位置已被占有时直接搜索下一个位置。

代码如下

#include<bits/stdc++.h>
using namespace std;
vector<int>a(10);
vector<int>num(10);
vector<int>v(10);
int flag=0;
bool check()
{
    int sum=a[1]+a[2]+a[3];
    if(a[4]+a[5]+a[6]!=sum||a[7]+a[8]+a[9]!=sum)return false;
    if(a[1]+a[4]+a[7]!=sum||a[2]+a[5]+a[8]!=sum||a[3]+a[6]+a[9]!=sum)return false;
    if(a[1]+a[5]+a[9]!=sum||a[3]+a[5]+a[7]!=sum)return false;
    return true;
}
void dfs(int pos)
{
    if(check()){
        flag++;
        if(flag==1){
            for(int i=1;i<=9;i++)v[i]=a[i];
        }
        return;
    }
    if(a[pos]!=0)dfs(pos+1);
    else{
        for(int k=1;k<=9;k++){
            if(num[k]==0){
                a[pos]=k;
                num[k]=1;
                dfs(pos+1);
                a[pos]=0;
                num[k]=0;
            }
        }
    }
}
int main()
{
    for(int i=1;i<=9;i++){cin>>a[i];num[a[i]]=1;}
    dfs(1);
    if(flag==1){
        for(int i=1;i<=9;i++){
            cout<<v[i];
            if(i%3==0){
                cout<<endl;
            }
            else cout<<" ";
        }
    }
    else cout<<"Too Many"<<endl;
    return 0;
}
View Code

 

原文地址:https://www.cnblogs.com/mohari/p/12864817.html