zoukankan      html  css  js  c++  java
  • hdu 2553 N皇后问题 (DFS)

    N皇后问题

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 6493    Accepted Submission(s): 2951


    Problem Description
    在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
    你的任务是,对于给定的N,求出有多少种合法的放置方法。

     
    Input
    共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
     
    Output
    共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
     
    Sample Input
    1 8 5 0
     
    Sample Output
    1 92 10
     
    Author
    cgf
     
    Source
     
    Recommend
    lcy   |   We have carefully selected several similar problems for you:  2614 1258 1426 1175 1067 
     
     1 //31MS    256K    993 B    C++
     2 //经典N皇后问题 深搜解法 
     3 #include<stdio.h>
     4 #include<string.h>
     5 int cnt,n;
     6 int q[15][15];
     7 int Judge(int x,int y)
     8 {
     9     for(int i=0;i<n;i++) if(q[x][i] && i!=y) return 0;
    10     for(int i=0;i<n;i++) if(q[i][y] && i!=x) return 0;
    11     for(int i=x+1,j=y+1;i<n && j<n;i++,j++)
    12         if(q[i][j]) return 0;
    13     for(int i=x-1,j=y-1;i>=0 && j>=0;i--,j--)
    14         if(q[i][j]) return 0;
    15     for(int i=x+1,j=y-1;i<n && j>=0;i++,j--)
    16         if(q[i][j]) return 0;
    17     for(int i=x-1,j=y+1;i>=0 && j<n;i--,j++)
    18         if(q[i][j]) return 0;
    19     return 1;
    20 }   
    21 void dfs(int c)
    22 {
    23     if(c==n){ cnt++;return;}
    24     for(int i=0;i<n;i++)
    25         if(Judge(i,c)){
    26             q[i][c]=1;
    27             dfs(c+1);
    28             q[i][c]=0;
    29         }
    30 }
    31 int main(void)
    32 {
    33     int a[15]={0};//不打表会超时 
    34     for(int i=1;i<11;i++){
    35         n=i;
    36         cnt=0;
    37         memset(q,0,sizeof(q));
    38         dfs(0);
    39         a[i]=cnt;
    40     }
    41     while(scanf("%d",&n)!=EOF && n)
    42     {
    43         printf("%d
    ",a[n]);
    44     }
    45     return 0;
    46 } 

    给出一个高效的位运算求法:

     1 //15MS    208K    704 B    G++ 
     2 #include<stdio.h>
     3 int ans[15];
     4 int sum;
     5 int upperlim;
     6 void dfs(int row,int ld,int rd) //某行中纵列不可取,左右对角线不可取的限制条件 
     7 {
     8     int pos,p;
     9     if(row!=upperlim){
    10         pos=upperlim&(~(row|ld|rd)); //取出可以放的位置 
    11         while(pos){
    12             p=pos&(~pos+1); //取pos最左边的1 
    13             pos=pos-p;   //减去可取的 
    14             dfs(row|p,(ld|p)<<1,(rd|p)>>1); //深搜 
    15         }
    16     }else sum++; //搜出来后总数+1 
    17 }
    18 int main(void)
    19 {
    20     for(int i=1;i<11;i++){
    21         sum=0;
    22         upperlim=(1<<i)-1; //i个1
    23         dfs(0,0,0);
    24         ans[i]=sum;
    25     }
    26     int n;
    27     while(scanf("%d",&n),n)
    28     {
    29         printf("%d
    ",ans[n]);
    30     }
    31     return 0;
    32 } 
  • 相关阅读:
    关于let 和 var 的作用域问题
    ES6数组新增方法总结
    Javascript中的async await
    Promise个人笔记---【Promise的前世今生】
    KEIL, MDK 关于C99结构体变量初始化
    C89,C99: C数组&结构体&联合体快速初始化
    13. DMA
    GPIO, AFIO
    27. USART, Universal synchronous asynchronous receiver transmitter
    中断控制及basepri 与 basepri_max
  • 原文地址:https://www.cnblogs.com/GO-NO-1/p/3477410.html
Copyright © 2011-2022 走看看