<p><a href="http://acm.hdu.edu.cn/showproblem.php?pid=1116">题目连接</a></p>
<p>经过思考,不难发现:恰好N个皇后放在不同行不同列,那么是不是可以转换成N个皇后所在行分别确定(一人一行)的情况下对她们的所在列的枚举。</p>
<p>也就是列的全排列生成问题,我们用c[x]表示x行皇后的列编号。而我们知道0~N-1的排列一共有N的阶乘,枚举量不会超过它。</p>
<p>if(cur==n)//递归边界。只要走到这里,所有的皇后必然不冲突<br /> tot++;</p>
<p>根据我们的代码,我们是从cur=0开始的,</p>
<div class="cnblogs_code">
<pre><span style="color: #008080;"> 1</span> #include<iostream>
<span style="color: #008080;"> 2</span> #include<cstdio>
<span style="color: #008080;"> 3</span> <span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span><span style="color: #000000;"> std;
</span><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">int</span> n,tot,c[<span style="color: #800080;">1000</span><span style="color: #000000;">];
</span><span style="color: #008080;"> 5</span> <span style="color: #0000ff;">void</span> search(<span style="color: #0000ff;">int</span><span style="color: #000000;"> cur)
</span><span style="color: #008080;"> 6</span> <span style="color: #000000;">{
</span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> i,j;
</span><span style="color: #008080;"> 8</span> <span style="color: #0000ff;">if</span>(cur==n)<span style="color: #008000;">//</span><span style="color: #008000;">递归边界。只要走到这里,所有的皇后必然不冲突</span>
<span style="color: #008080;"> 9</span> tot++<span style="color: #000000;">;
</span><span style="color: #008080;">10</span> <span style="color: #0000ff;">else</span>
<span style="color: #008080;">11</span> <span style="color: #0000ff;">for</span>(i=<span style="color: #800080;">0</span>;i<n;i++<span style="color: #000000;">)
</span><span style="color: #008080;">12</span> <span style="color: #000000;"> {
</span><span style="color: #008080;">13</span> <span style="color: #0000ff;">int</span> ok=<span style="color: #800080;">1</span><span style="color: #000000;">;
</span><span style="color: #008080;">14</span> c[cur]=i;<span style="color: #008000;">//</span><span style="color: #008000;">尝试把第cur行的皇后放在第i列</span>
<span style="color: #008080;">15</span> <span style="color: #0000ff;">for</span>(j=<span style="color: #800080;">0</span>;j<cur;j++<span style="color: #000000;">)
</span><span style="color: #008080;">16</span> <span style="color: #0000ff;">if</span>(c[cur]==c[j]||cur-c[cur]==j-c[j]||cur+c[cur]==j+c[j])<span style="color: #008000;">//</span><span style="color: #008000;">检查是否与前面的皇后冲突</span>
<span style="color: #008080;">17</span> <span style="color: #000000;"> {
</span><span style="color: #008080;">18</span> ok=<span style="color: #800080;">0</span>;<span style="color: #0000ff;">break</span><span style="color: #000000;">;
</span><span style="color: #008080;">19</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">20</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(ok)
</span><span style="color: #008080;">21</span> search(cur+<span style="color: #800080;">1</span>);<span style="color: #008000;">//</span><span style="color: #008000;">如果合法,继续递归</span>
<span style="color: #008080;">22</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">23</span> <span style="color: #000000;">}
</span><span style="color: #008080;">24</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> main()
</span><span style="color: #008080;">25</span> <span style="color: #000000;">{
</span><span style="color: #008080;">26</span> <span style="color: #0000ff;">int</span> a[<span style="color: #800080;">15</span><span style="color: #000000;">];
</span><span style="color: #008080;">27</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">int</span> i=<span style="color: #800080;">0</span>;i<<span style="color: #800080;">10</span>;i++<span style="color: #000000;">){
</span><span style="color: #008080;">28</span> tot=<span style="color: #800080;">0</span><span style="color: #000000;">;
</span><span style="color: #008080;">29</span> n=i+<span style="color: #800080;">1</span><span style="color: #000000;">;
</span><span style="color: #008080;">30</span> search(<span style="color: #800080;">0</span><span style="color: #000000;">);
</span><span style="color: #008080;">31</span> a[n]=<span style="color: #000000;">tot;
</span><span style="color: #008080;">32</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">33</span> <span style="color: #0000ff;">while</span>(cin>>n&&<span style="color: #000000;">n)
</span><span style="color: #008080;">34</span> <span style="color: #000000;"> {
</span><span style="color: #008080;">35</span> cout<<a[n]<<<span style="color: #000000;">endl;
</span><span style="color: #008080;">36</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">37</span> }</pre>
</div>
<p>search(cur+1);//如果合法,继续递归 并不会判断n+1行的皇后。所以我们从cur=0开始。</p>
<p>当然从cur=1开始也是可以的,但此时</p>
<p> if(cur==n+1)//递归边界。只要走到这里,所有的皇后必然不冲突</p>
<p>tot++;</p>
<p>程序中的</p>
<p>if(c[cur]==c[j]||cur-c[cur]==j-c[j]||cur+c[cur]==j+c[j])//检查是否与前面的皇后冲突<br /> {<br /> ok=0;break;<br /> }</p>
<p>既然是逐行放置,那么皇后肯定不会横向攻击,因此只需检查是否纵向和斜向攻击即可。条件c[cur]==c[j]||cur-c[cur]==j-c[j]||cur+c[cur]==j+c[j])</p>
<p> y-x标示了主对角线,斜率为1;</p>
<p> y+x标示了副对角线,斜率为-1;</p>
<p>画画图就知道了</p>
<p>我们还可以用二维数组vis[2][]直接判断当前尝试放的皇后的对角线和纵向有没有皇后已经放了,注意主对角线标示y-x可能为负数,所以要加n</p>
<p> </p>
<div class="cnblogs_code">
<pre><span style="color: #008080;"> 1</span> #include<iostream>
<span style="color: #008080;"> 2</span> #include<cstdio>
<span style="color: #008080;"> 3</span> #include<algorithm>
<span style="color: #008080;"> 4</span> #include<cstring>
<span style="color: #008080;"> 5</span> <span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span><span style="color: #000000;"> std;
</span><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">int</span> n,tot,c[<span style="color: #800080;">1000</span><span style="color: #000000;">];
</span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">int</span> vis[<span style="color: #800080;">3</span>][<span style="color: #800080;">1000</span><span style="color: #000000;">];
</span><span style="color: #008080;"> 8</span> <span style="color: #0000ff;">void</span> search(<span style="color: #0000ff;">int</span><span style="color: #000000;"> cur)
</span><span style="color: #008080;"> 9</span> <span style="color: #000000;">{
</span><span style="color: #008080;">10</span> <span style="color: #0000ff;">if</span>(cur==n)tot++<span style="color: #000000;">;
</span><span style="color: #008080;">11</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">{
</span><span style="color: #008080;">12</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">int</span> i=<span style="color: #800080;">0</span>;i<n;i++<span style="color: #000000;">){
</span><span style="color: #008080;">13</span> <span style="color: #0000ff;">if</span>(!vis[<span style="color: #800080;">0</span>][i]&&!vis[<span style="color: #800080;">1</span>][cur+i]&&!vis[<span style="color: #800080;">2</span>][cur-i+<span style="color: #000000;">n]){
</span><span style="color: #008080;">14</span> c[cur]=i;<span style="color: #008000;">//</span><span style="color: #008000;">如果不需要打印皇后所在列,可以舍去</span>
<span style="color: #008080;">15</span> vis[<span style="color: #800080;">0</span>][i]=vis[<span style="color: #800080;">1</span>][cur+i]=vis[<span style="color: #800080;">2</span>][cur-i+n]=<span style="color: #800080;">1</span>;<span style="color: #008000;">//</span><span style="color: #008000;">标示这些空已经不能再放皇后</span>
<span style="color: #008080;">16</span> search(cur+<span style="color: #800080;">1</span><span style="color: #000000;">);
</span><span style="color: #008080;">17</span> vis[<span style="color: #800080;">0</span>][i]=vis[<span style="color: #800080;">1</span>][cur+i]=vis[<span style="color: #800080;">2</span>][cur-i+n]=<span style="color: #800080;">0</span>;<span style="color: #008000;">//</span><span style="color: #008000;">回溯要改回来</span>
<span style="color: #008080;">18</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">19</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">20</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">21</span> <span style="color: #000000;">}
</span><span style="color: #008080;">22</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> main()
</span><span style="color: #008080;">23</span> <span style="color: #000000;">{
</span><span style="color: #008080;">24</span> <span style="color: #0000ff;">int</span> a[<span style="color: #800080;">15</span><span style="color: #000000;">];
</span><span style="color: #008080;">25</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">int</span> i=<span style="color: #800080;">0</span>;i<<span style="color: #800080;">10</span>;i++<span style="color: #000000;">){
</span><span style="color: #008080;">26</span> memset(vis,<span style="color: #800080;">0</span>,<span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(vis));
</span><span style="color: #008080;">27</span> tot=<span style="color: #800080;">0</span><span style="color: #000000;">;
</span><span style="color: #008080;">28</span> n=i+<span style="color: #800080;">1</span><span style="color: #000000;">;
</span><span style="color: #008080;">29</span> search(<span style="color: #800080;">0</span><span style="color: #000000;">);
</span><span style="color: #008080;">30</span> a[n]=<span style="color: #000000;">tot;
</span><span style="color: #008080;">31</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">32</span> <span style="color: #0000ff;">while</span>(cin>>n&&<span style="color: #000000;">n)
</span><span style="color: #008080;">33</span> <span style="color: #000000;"> {
</span><span style="color: #008080;">34</span> cout<<a[n]<<<span style="color: #000000;">endl;
</span><span style="color: #008080;">35</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">36</span> }</pre>
</div>
<p> </p>
<p>经过思考,不难发现:恰好N个皇后放在不同行不同列,那么是不是可以转换成N个皇后所在行分别确定(一人一行)的情况下对她们的所在列的枚举。</p>
<p>也就是列的全排列生成问题,我们用c[x]表示x行皇后的列编号。而我们知道0~N-1的排列一共有N的阶乘,枚举量不会超过它。</p>
<p>if(cur==n)//递归边界。只要走到这里,所有的皇后必然不冲突<br /> tot++;</p>
<p>根据我们的代码,我们是从cur=0开始的,</p>
<div class="cnblogs_code">
<pre><span style="color: #008080;"> 1</span> #include<iostream>
<span style="color: #008080;"> 2</span> #include<cstdio>
<span style="color: #008080;"> 3</span> <span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span><span style="color: #000000;"> std;
</span><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">int</span> n,tot,c[<span style="color: #800080;">1000</span><span style="color: #000000;">];
</span><span style="color: #008080;"> 5</span> <span style="color: #0000ff;">void</span> search(<span style="color: #0000ff;">int</span><span style="color: #000000;"> cur)
</span><span style="color: #008080;"> 6</span> <span style="color: #000000;">{
</span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> i,j;
</span><span style="color: #008080;"> 8</span> <span style="color: #0000ff;">if</span>(cur==n)<span style="color: #008000;">//</span><span style="color: #008000;">递归边界。只要走到这里,所有的皇后必然不冲突</span>
<span style="color: #008080;"> 9</span> tot++<span style="color: #000000;">;
</span><span style="color: #008080;">10</span> <span style="color: #0000ff;">else</span>
<span style="color: #008080;">11</span> <span style="color: #0000ff;">for</span>(i=<span style="color: #800080;">0</span>;i<n;i++<span style="color: #000000;">)
</span><span style="color: #008080;">12</span> <span style="color: #000000;"> {
</span><span style="color: #008080;">13</span> <span style="color: #0000ff;">int</span> ok=<span style="color: #800080;">1</span><span style="color: #000000;">;
</span><span style="color: #008080;">14</span> c[cur]=i;<span style="color: #008000;">//</span><span style="color: #008000;">尝试把第cur行的皇后放在第i列</span>
<span style="color: #008080;">15</span> <span style="color: #0000ff;">for</span>(j=<span style="color: #800080;">0</span>;j<cur;j++<span style="color: #000000;">)
</span><span style="color: #008080;">16</span> <span style="color: #0000ff;">if</span>(c[cur]==c[j]||cur-c[cur]==j-c[j]||cur+c[cur]==j+c[j])<span style="color: #008000;">//</span><span style="color: #008000;">检查是否与前面的皇后冲突</span>
<span style="color: #008080;">17</span> <span style="color: #000000;"> {
</span><span style="color: #008080;">18</span> ok=<span style="color: #800080;">0</span>;<span style="color: #0000ff;">break</span><span style="color: #000000;">;
</span><span style="color: #008080;">19</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">20</span> <span style="color: #0000ff;">if</span><span style="color: #000000;">(ok)
</span><span style="color: #008080;">21</span> search(cur+<span style="color: #800080;">1</span>);<span style="color: #008000;">//</span><span style="color: #008000;">如果合法,继续递归</span>
<span style="color: #008080;">22</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">23</span> <span style="color: #000000;">}
</span><span style="color: #008080;">24</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> main()
</span><span style="color: #008080;">25</span> <span style="color: #000000;">{
</span><span style="color: #008080;">26</span> <span style="color: #0000ff;">int</span> a[<span style="color: #800080;">15</span><span style="color: #000000;">];
</span><span style="color: #008080;">27</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">int</span> i=<span style="color: #800080;">0</span>;i<<span style="color: #800080;">10</span>;i++<span style="color: #000000;">){
</span><span style="color: #008080;">28</span> tot=<span style="color: #800080;">0</span><span style="color: #000000;">;
</span><span style="color: #008080;">29</span> n=i+<span style="color: #800080;">1</span><span style="color: #000000;">;
</span><span style="color: #008080;">30</span> search(<span style="color: #800080;">0</span><span style="color: #000000;">);
</span><span style="color: #008080;">31</span> a[n]=<span style="color: #000000;">tot;
</span><span style="color: #008080;">32</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">33</span> <span style="color: #0000ff;">while</span>(cin>>n&&<span style="color: #000000;">n)
</span><span style="color: #008080;">34</span> <span style="color: #000000;"> {
</span><span style="color: #008080;">35</span> cout<<a[n]<<<span style="color: #000000;">endl;
</span><span style="color: #008080;">36</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">37</span> }</pre>
</div>
<p>search(cur+1);//如果合法,继续递归 并不会判断n+1行的皇后。所以我们从cur=0开始。</p>
<p>当然从cur=1开始也是可以的,但此时</p>
<p> if(cur==n+1)//递归边界。只要走到这里,所有的皇后必然不冲突</p>
<p>tot++;</p>
<p>程序中的</p>
<p>if(c[cur]==c[j]||cur-c[cur]==j-c[j]||cur+c[cur]==j+c[j])//检查是否与前面的皇后冲突<br /> {<br /> ok=0;break;<br /> }</p>
<p>既然是逐行放置,那么皇后肯定不会横向攻击,因此只需检查是否纵向和斜向攻击即可。条件c[cur]==c[j]||cur-c[cur]==j-c[j]||cur+c[cur]==j+c[j])</p>
<p> y-x标示了主对角线,斜率为1;</p>
<p> y+x标示了副对角线,斜率为-1;</p>
<p>画画图就知道了</p>
<p>我们还可以用二维数组vis[2][]直接判断当前尝试放的皇后的对角线和纵向有没有皇后已经放了,注意主对角线标示y-x可能为负数,所以要加n</p>
<p> </p>
<div class="cnblogs_code">
<pre><span style="color: #008080;"> 1</span> #include<iostream>
<span style="color: #008080;"> 2</span> #include<cstdio>
<span style="color: #008080;"> 3</span> #include<algorithm>
<span style="color: #008080;"> 4</span> #include<cstring>
<span style="color: #008080;"> 5</span> <span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span><span style="color: #000000;"> std;
</span><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">int</span> n,tot,c[<span style="color: #800080;">1000</span><span style="color: #000000;">];
</span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">int</span> vis[<span style="color: #800080;">3</span>][<span style="color: #800080;">1000</span><span style="color: #000000;">];
</span><span style="color: #008080;"> 8</span> <span style="color: #0000ff;">void</span> search(<span style="color: #0000ff;">int</span><span style="color: #000000;"> cur)
</span><span style="color: #008080;"> 9</span> <span style="color: #000000;">{
</span><span style="color: #008080;">10</span> <span style="color: #0000ff;">if</span>(cur==n)tot++<span style="color: #000000;">;
</span><span style="color: #008080;">11</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">{
</span><span style="color: #008080;">12</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">int</span> i=<span style="color: #800080;">0</span>;i<n;i++<span style="color: #000000;">){
</span><span style="color: #008080;">13</span> <span style="color: #0000ff;">if</span>(!vis[<span style="color: #800080;">0</span>][i]&&!vis[<span style="color: #800080;">1</span>][cur+i]&&!vis[<span style="color: #800080;">2</span>][cur-i+<span style="color: #000000;">n]){
</span><span style="color: #008080;">14</span> c[cur]=i;<span style="color: #008000;">//</span><span style="color: #008000;">如果不需要打印皇后所在列,可以舍去</span>
<span style="color: #008080;">15</span> vis[<span style="color: #800080;">0</span>][i]=vis[<span style="color: #800080;">1</span>][cur+i]=vis[<span style="color: #800080;">2</span>][cur-i+n]=<span style="color: #800080;">1</span>;<span style="color: #008000;">//</span><span style="color: #008000;">标示这些空已经不能再放皇后</span>
<span style="color: #008080;">16</span> search(cur+<span style="color: #800080;">1</span><span style="color: #000000;">);
</span><span style="color: #008080;">17</span> vis[<span style="color: #800080;">0</span>][i]=vis[<span style="color: #800080;">1</span>][cur+i]=vis[<span style="color: #800080;">2</span>][cur-i+n]=<span style="color: #800080;">0</span>;<span style="color: #008000;">//</span><span style="color: #008000;">回溯要改回来</span>
<span style="color: #008080;">18</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">19</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">20</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">21</span> <span style="color: #000000;">}
</span><span style="color: #008080;">22</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> main()
</span><span style="color: #008080;">23</span> <span style="color: #000000;">{
</span><span style="color: #008080;">24</span> <span style="color: #0000ff;">int</span> a[<span style="color: #800080;">15</span><span style="color: #000000;">];
</span><span style="color: #008080;">25</span> <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">int</span> i=<span style="color: #800080;">0</span>;i<<span style="color: #800080;">10</span>;i++<span style="color: #000000;">){
</span><span style="color: #008080;">26</span> memset(vis,<span style="color: #800080;">0</span>,<span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(vis));
</span><span style="color: #008080;">27</span> tot=<span style="color: #800080;">0</span><span style="color: #000000;">;
</span><span style="color: #008080;">28</span> n=i+<span style="color: #800080;">1</span><span style="color: #000000;">;
</span><span style="color: #008080;">29</span> search(<span style="color: #800080;">0</span><span style="color: #000000;">);
</span><span style="color: #008080;">30</span> a[n]=<span style="color: #000000;">tot;
</span><span style="color: #008080;">31</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">32</span> <span style="color: #0000ff;">while</span>(cin>>n&&<span style="color: #000000;">n)
</span><span style="color: #008080;">33</span> <span style="color: #000000;"> {
</span><span style="color: #008080;">34</span> cout<<a[n]<<<span style="color: #000000;">endl;
</span><span style="color: #008080;">35</span> <span style="color: #000000;"> }
</span><span style="color: #008080;">36</span> }</pre>
</div>
<p> </p>