[蓝桥杯2015决赛]四阶幻方(控制递归路线)(耗时较少35ms)

#include
#include
using namespace std;
int dx[9]={0,1,1,0,-1,-1,-1,0,1},dy[9]={0,1,1,-3,1,1,1,-1,1},vis[34],v[5][5],ans=0;//dx,dy是规划路线(即先走完对角线)
void dfs(int x,int y,int z){//x,y坐标,z是层数对应dx,dy数组,控制递归路线
    if(z>=8){//对角线走完再走(1,3),此时(直接用其他坐标算出(1,2),(4,3),(4,2)
        if(z==8){
            if(v[1][4]+v[2][3]+v[3][2]+v[4][1]!=34)  return;//验证对角线
            for(int i=2;i<=16;i++){
                if(vis[i]==0){
                    v[x][y]=i;
                    v[1][2]=34-v[x][y]-v[1][1]-v[1][4];
                    v[4][3]=34-v[x][y]-v[2][3]-v[3][3];
                    v[4][2]=34-v[4][1]-v[4][3]-v[4][4];
                    if(v[1][2]<0||vis[v[1][2]]==1) continue;//验证
                    if(v[4][3]<0||vis[v[4][3]]==1) continue;
                    if(v[4][2]<0||vis[v[4][2]]==1) continue;
                    if(v[1][2]+v[2][2]+v[3][2]+v[4][2]!=34) continue;
                    if(i==v[1][2]||i==v[4][3]||i==v[4][2]||v[1][2]==v[4][3]||v[1][2]==v[4][2]||v[4][3]==v[4][2]) continue;
                    vis[v[1][2]]=1,vis[v[x][y]]=1,vis[v[4][3]]=1,vis[v[4][2]]=1;
                    dfs(x+dx[z],y+dy[z],z+1);
                    vis[v[1][2]]=0,vis[v[x][y]]=0,vis[v[4][3]]=0,vis[v[4][2]]=0;//回溯
                }
            }
        }
        else{//此时只剩(2,1),(3,1),(2,4),(3,4)跟上面算法相同,此时(x=2,y=4)
            for(int i=2;i<=16;i++){
                if(vis[i]==0){
                    v[x][y]=i;
                    v[2][1]=34-v[x][y]-v[2][2]-v[2][3];
                    v[3][4]=34-v[x][y]-v[1][4]-v[4][4];
                    v[3][1]=34-v[3][2]-v[3][3]-v[3][4];
                    if(v[2][1]<0||vis[v[2][1]]==1) continue;
                    if(v[3][4]<0||vis[v[3][4]]==1) continue;
                    if(v[3][1]<0||vis[v[3][1]]==1) continue;
                    if(v[1][1]+v[2][1]+v[3][1]+v[4][1]!=34) continue;
                    if(i==v[2][1]||i==v[3][4]||i==v[3][1]||v[2][1]==v[3][4]||v[2][1]==v[3][1]||v[3][4]==v[3][1]) continue;
                    ans++;
                    continue;
                }
            }
        }
    }
    else{
        if(z==4&&v[1][1]+v[2][2]+v[3][3]+v[4][4]!=34)  return;//验证对角线
        for(int i=2;i<=16;i++){
            if(vis[i]==0){
                v[x][y]=i;
                vis[i]=1;
                dfs(x+dx[z],y+dy[z],z+1);
                vis[i]=0;
            }
        }
    }
}
int main (){
    v[1][1]=1;
    vis[1]=1;//(1,1)点确定
    fill(vis,vis+34,1);
    for(int i=2;i<=16;i++)
    vis[i]=0;
    dfs(2,2,1);
    cout< }

你可能感兴趣的:([蓝桥杯2015决赛]四阶幻方(控制递归路线)(耗时较少35ms))