四阶幻方-蓝桥杯-DFS

答案:416

用next_permutation()全部排列的话会超时

所以用dfs搜索,只搜索前三行就好,前三行确定之后,第四行也就确定

#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
using namespace std;
int vis[17],a[5][5];
int ans=0;
int check(int x,int y)
{
    if(x<3)//只枚举到前三行就可以,如果前三行符合条件,那么最后一行四个数之和一定是34
    {
        if(y<3)//一行还没有放满4个,前三个数可以随便取
            return 1;
        if(a[x][0]+a[x][1]+a[x][2]+a[x][3]==34)
            return 1;
        else
        {
            return 0;
        }
    }
    else//x==3
    {
        if(y==0)//判断第1列和副对角线
        {
            if((a[0][0]+a[1][0]+a[2][0]+a[3][0]!=34)||(a[0][3]+a[1][2]+a[2][1]+a[3][0]!=34)) 
                return 0;
        }
        if(y==1||y==2)//判断第2列和第3列
            if(a[0][y]+a[1][y]+a[2][y]+a[3][y]!=34) 
                return 0;
        if(y==3)//判断第4列和主对角线
            if((a[0][y]+a[1][y]+a[2][y]+a[3][y]!=34)||(a[0][0]+a[1][1]+a[2][2]+a[3][3])!=34) 
                return 0;
        else
        {
            return 1;
        }
        
    }
    
}
void dfs(int x,int y)
{
    if(x==4)
    {
        ans++;
        return ;
    }
    // else if(y>3)
    //     dfs(x+1,0);
    else
    {
        for(int i=2;i<=16;i++)
        {
            if(vis[i]==0)
            {
                vis[i]=1;
                a[x][y]=i;
                if(check(x,y))
                {
                    if(y<3)
                        dfs(x,y+1);
                    else
                        dfs(x+1,0);
                }
                vis[i]=0;    
            }
            
        }
    }
    
    
}
int main()
{
    a[0][0]=vis[1]=1;
    dfs(0,1);
    cout<<ans<<endl;
    system("pause");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/-citywall123/p/12300306.html