HDU2553-回溯-N皇后问题

https://vjudge.net/problem/HDU-2553
中文题意。
开始的写法竟然多算了好多,不知道为啥。
后来转变了写法。 发现对角线有规律。
一个是 和是固定的,另一个是差值是固定的(类似斜率)

#include <bits/stdc++.h>
using namespace std;
/*不知道为什么错,错误的写法

*/
const int maxn=30;
bool vis[maxn][maxn];
int m;
int sum;
queue<int>q;
void  dfs(int cengci){
    if(cengci==m+1) {sum++;
    /*cout<<cengci<<"!!!!!"<<endl;
    for(int i=1;i<=m;i++){
        for(int j=1;j<=m;j++)
             if(vis[i][j])
              cout<<"1 ";
            else
                cout<<"0 ";
        cout<<endl;
    }
    cout<<"________________________"<<endl;
   queue<int>s=q;
   while(!s.empty()){
     int u=s.front();
      cout<<u<<" ";
      s.pop();
     }
     cout<<endl;
     cout<<"***********************"<<endl;
     q.pop();*/
    return ;}
    for(int i=1;i<=m;i++){
        if(!vis[cengci][i]){
           for(int x=1;x+i<=m+1&&cengci+x<=m+1;x++){
             vis[cengci+x][x+i]=true;//对角线向下右侧
             }
             for(int x=1;cengci-x>=1&&i-x>=1;x++)
                vis[cengci-x][i-x]=true;//对角线向下左
             for(int x=1;cengci-x>=1&&i+x<=m;x++)
                vis[cengci-x][i+x]=true;//对角线向上右
             for(int x=1;i-x>=1&&cengci+x<=m+1;x++)
                vis[cengci+x][i-x]=true;//对角线向上左
            for(int x=1;x<=m;x++)
             {vis[x][i]=true;//竖直,
              vis[cengci][x]=true;//横向
             }
           dfs(cengci+1);
           q.push(i);
           for(int x=1;x+i<=m+1&&cengci+x<=m+1;x++)
             vis[cengci+x][x+i]=false;
             for(int x=1;i-x>=1&&cengci+x<=m+1;x++)
            vis[cengci+x][i-x]=false;
           for(int x=1;x<=m;x++)
             {vis[x][i]=false;
              vis[cengci][x]=false;
             }
              for(int x=1;cengci-x>=1&&i-x>=1;x++)
                vis[cengci-x][i-x]=false;
             for(int x=1;cengci-x>=1&&i+x<=m;x++)
                vis[cengci-x][i+x]=false;
        }
    }
}
int main()
{
     while(~scanf("%d",&m)){
           sum=0;
           memset(vis,false,sizeof(vis));
           dfs(1);
           printf("%d\n",sum);
     }
    return 0;
}

ac的

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
const int maxn=20;
int vis[3][maxn];
int m;
int sum;
void dfs(int cengci){
     if(cengci==m+1)
     {sum++;return;}
     for(int i=1;i<=m;i++){
         if(!vis[0][i]&&!vis[1][cengci-i+m]&&!vis[2][cengci+i])
         {    vis[0][i]=true;
              vis[1][cengci-i+m]=true;
              vis[2][cengci+i]=true;
              dfs(cengci+1);
              vis[0][i]=false;
              vis[1][cengci-i+m]=false;
              vis[2][cengci+i]=false;
         }
     }
}
int main()
{   int dp[11];
    for(int i=1;i<=10;i++){
        m=i;
        memset(vis,false,sizeof(vis));
        sum=0;
        dfs(1);
        dp[i]=sum;
    }
    while(~scanf("%d",&m)){
         if(!m) break;
         printf("%d\n",dp[m]);

    }


    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值