N皇后问题

最近研究N皇后问题,研究了两天两夜,根本想不明白,还被别人嫌弃我是菜鸡,真的哭出来了...

后来发现是模板有问题,太可恶了!!

现在我给大家发一下我搜集到的正确模板:

模板一:

#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;

bool b[100], c[100], d[100];
int n, que[20], ans[20], count1;

/*bool isplace(int num,int x)
{

    for(int i = 1;i<num;i++)//到num的前num-1行无重复
    {

        if(x == que[i])//x等于其所在列数
                return false;
        if(abs(num - i) == abs(x - que[i]))
        {
            return false;
        }
    }
    return true;
}*/

void dfs(int num)
{

    if(num > n)
    {
        count1++;
        if(count1 > 3)
            return;
        if(count1 <= 3)
        {
            printf("%d", que[1]);
            for(int i = 2;i <= n;i++)
            {

                printf(" %d",que[i]);
            }
            printf("\n");
        }
        return;
    }
    
    for(int i = 1; i <= n; i++)
    {
        if((!b[i]) && (!c[i+num]) && (!d[num-i+n]))
        {
             que[num] = i;
             b[i] = 1;//纵列
             c[num + i] = 1;
             d[num - i + n] = 1;//两条对角线。
             dfs(num + 1);
             b[i] = 0;
             c[num + i] = 0;
             d[num - i+n] = 0;

        }
    }
    return;
}
int main()
{
    scanf("%d", &n);
    count1 = 0;
    
    dfs(1);
    printf("%d\n", count1);
    return 0;
}

模板二:

#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
int n,k,ans;
char c;
bool h[10],rx[100],ry[100];
void dfs(int i)
{
    //cout<<"i="<<i<<endl;
    if(i==n+1)
    {
        ans++;
        return;
    }
    for(int j=1;j<=n;j++)
    if(h[j]&&rx[j-i+10]==0&&ry[i+j]==0)
    {
       // cout<<i<<' '<<j<<endl;
        h[j]=0;
        rx[j-i+10]=1;
        ry[i+j]=1;
        dfs(i+1);
        rx[j-i+10]=0;
        ry[i+j]=0;
        h[j]=1;
    }
}
int main()
{
    scanf("%d",&n);
    while(n)
    {
        ans=0;
        memset(h,1,sizeof(h));
        memset(rx,0,sizeof(rx));
        memset(ry,0,sizeof(ry));
        dfs(1);
        printf("%d\n",ans);
        scanf("%d",&n);
    }
    return 0;
}
*/


#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
int n,k;
long long s[11],ans;
char c;
bool h[11],rx[100],ry[100];
void dfs(int i,int x)
{
    //cout<<"i="<<i<<endl;
    if(i==x+1)
    {
        ans++;
        return;
    }
    for(int j=1;j<=x;j++)
    if(h[j]&&rx[j-i+10]==0&&ry[i+j]==0)      //对角线上的要么和相等,要么差相等 
    {
       // cout<<i<<' '<<j<<endl;
        h[j]=0;
        rx[j-i+10]=1;
        ry[i+j]=1;
        dfs(i+1,x);
        rx[j-i+10]=0;
        ry[i+j]=0;
        h[j]=1;
    }
}
int main()
{
    for(int i=1;i<=10;i++)
    {
        memset(h,1,sizeof(h));
        memset(rx,0,sizeof(rx));
        memset(ry,0,sizeof(ry));
        ans=0;
        dfs(1,i);
        s[i]=ans;
    }
    scanf("%d",&n);
    while(n)
    {
        printf("%lld\n",s[n]);
        scanf("%d",&n);
    }
    return 0;
}

模板三:

#include<stdio.h>  
#define N 15  
  
int n; //皇后个数  
int sum = 0; //可行解个数  
int x[N]; //皇后放置的列数  
  
/* 
 *判断函数,判断第k个皇后是否可以放在某一个位置 
 *如果与之前的皇后出现在同一列或同一对角线则放置失败,返回0,否则返回1 
*/  
int place(int k)  
{  
    int i;  
    for(i=1;i<k;i++)  
      if(abs(k-i)==abs(x[k]-x[i]) || x[k] == x[i])  
        return 0;  
    return 1;  
}  
  
/* 
 *求解可行解函数,当第t个皇后可以放置在t行的某一位置时,继续放置下一皇后,直到 
 *所有皇后放置结束,如果某一皇后不能放置,则移向下一列放置,如果这一列都不能放 
 *置或所有皇后放置结束,返回上一皇后重新放置,最终返回所有可行解个数。 
*/  
int queen(int t)  
{  
    if(t>n && n>0) //当放置的皇后超过n时,可行解个数加1,此时n必须大于0  
      sum++;  
    else  
      for(int i=1;i<=n;i++)  
      {  
          x[t] = i; //标明第t个皇后放在第i列  
          if(place(t)) //如果可以放在某一位置,则继续放下一皇后  
            queen(t+1);   
      }  
    return sum;  
}  
  
int main()  
{  
    int t;  
    scanf("%d",&n);  
    t = queen(1);  
    if(n == 0) //如果n=0,则可行解个数为0,这种情况一定不要忽略  
      t = 0;  
    printf("%d",t);  
    return 0;  
}  

模板四:

#include<stdio.h>  
#define N 15  
  
int n;  
int sum = 0;  
int x[N];  
  
int place(int k)  
{  
    int i;  
    for(i=1;i<k;i++)  
      if(abs(k-i)==abs(x[k]-x[i]) || x[k] == x[i])  
        return 0;  
    return 1;  
}  
  
int queen()  
{  
      x[1] = 0;  
      int t=1;  
      while(t>0)  
      {  
          x[t]+=1;  
          while(x[t]<=n && !place(t))  
              x[t]++;  
          if(x[t]<=n)  
            if(t == n)  
              sum++;  
            else  
              x[++t] = 0;  
          else  
            t--;  
      }  
      return sum;  
}  
  
int main()  
{  
    int t;  
    scanf("%d",&n);  
    t = queen();  
    printf("%d",t);  
    return 0;  
}  

好了,这就是我研究了两天的结果,被人嫌弃菜,真的很可怜,还是继续加油吧~

posted @ 2018-11-28 21:33  明霞  阅读(273)  评论(0编辑  收藏  举报