2. N 皇后问题

题目链接(码学堂)

题目链接(洛谷)

分析:

对于一个二维且每行每列解唯一的bool题(无附加条件(有也可以结构体))

我们可以用一个 ans[i]=n ,下标i表示行,数据n表示列的一位数组来模拟

 

有三个限制条件

分别是行(vis)不能一样,对角线(diag)不能一样,副对角线(condiag)不能一样

我们分别用一维数组模拟,下标存储坐标要求,数据存储标记与否

 

代码:

 1 #include<iostream>
 2 #include<cmath>
 3 #include<cstdio>
 4 using namespace std;
 5 int N;
 6 int ans[100];//数不对就是溢出了 
 7 bool vis[100],diag[100],condiag[100];//面向每一行的列 
 8 int cnt;
 9 void print()
10 {
11     for(int i=1;i<=N;i++)
12         printf("%d ",ans[i]);
13     cout<<endl;
14 }
15 void DFS(int x)//第几行 
16 {
17     if(x==N+1)
18     {
19         cnt++;
20 //        if(cnt<=3)
21         print();
22         return ;
23     }
24     for(int i=1;i<=N;i++)
25     {
26         int t=x+i,t2=x-i+10; //和与差(差可能<0而越界,因此全部右移) 
27         if(vis[i]==0&&diag[t2]==0&&condiag[t]==0)
28         {
29             vis[i]=1;
30             diag[t2]=1;
31             condiag[t]=1;
32             ans[x]=i;
33             
34             DFS(x+1);
35 
36             vis[i]=0;
37             diag[t2]=0;
38             condiag[t]=0;
39             ans[x]=0;        
40         }
41     }
42     
43 }
44 int main()
45 {
46     cin>>N;
47     DFS(1);
48     if(cnt==0)
49      cout<<"no solute!";
50      else 
51          cout<<cnt;
52 
53     return 0;
54 }

注意事项(调试点):

1.数组一定要开大。结果出现忽然小的数据时检查数组规模

2.abs不要随便用在坐标做差上,验算是否会有误差

(坐标做差害怕越界  最好写越界函数或者整体平移

3.写完后检查一遍基本的运算有没有写错变量(第26行)

(运算表达式用变量代替,方便更改)

 

 

待调试(二维数组如何实现)(代码错误)

 

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int N;
 5 bool vis[50][50];
 6 int ans[15];
 7 void DFS(int x,int y);
 8 void print();
 9 int main()
10 {
11     cin>>N;
12     DFS(1,1);
13     return 0;
14 }
15 void DFS(int x,int y)
16 {
17     if(x==N)
18     {
19         print();
20         return ;
21      } 
22     for(int i=1;i<=N;i++)
23     {
24         if(vis[i][1]==1) continue;
25         for(int j=1;j<=N;j++)
26         {
27             if(vis[i][j]==0)
28             {
29                 vis[i][j]=1;
30                 ans[i]=j;
31                 for(int k=1;k<=N;k++)
32                 {
33                     if(i+j-k<=0||k+i-j<=0) continue;
34                     vis[i][k]=1;
35                     vis[k][j]=1;
36                     vis[(i+j)-k][k]=1;
37                     vis[k+(i-j)][k]=1;
38                 }
39                 DFS(i,j);
40                 vis[i][j]=0;
41                 ans[i]=0;
42                 for(int k=1;k<=N;k++)
43                 {
44                     if(i+j-k<=0||k+i-j<=0) continue;
45                     vis[i][k]=0;
46                     vis[k][j]=0;
47                     vis[(i+j)-k][k]=0;
48                     vis[k+(i-j)][k]=0;
49                 }
50             }
51         }
52     }
53 }
54 void print()
55 {
56     for(int i=1;i<=N;i++)
57          printf("%5d",ans[i]);
58     cout<<endl;        
59 }

 

posted @ 2022-08-23 17:03  要不要吃哈密瓜  阅读(63)  评论(0编辑  收藏  举报