69,374
社区成员
发帖
与我相关
我的任务
分享
#include <stdio.h>
#define N 8
char board2[N + 2][N + 2];
int QueenPos2[N];
int count2 = 0;
//定义一个方向的结构体
typedef struct _Tag_Pos
{
int xpos;
int ypos;
}Pos2;
Pos2 pos2[3] = { { -1, -1 }, { -1, 0 }, { -1, 1 } };
void init2(void);
void display2(void);
int check2(int x, int y);
void find2(void);
int main(int argc, char *argv[])
{
init2();
find2();
return 0;
}
//初始化
void init2(void)
{
for (int i = 0; i < N;i++)
{
QueenPos2[i] = 1;
}
for (int i = 0; i < N + 2; i++)
{
for (int j = 0; j < N + 2; j++)
{
if ((i == 0) || (i == N + 1))
{
board2[i][j] = '#';
}
else if ((j == 0) || (j == N + 1))
{
board2[i][j] = '#';
}
else
{
board2[i][j] = ' ';
}
}
}
}
//输出
void display2(void)
{
for (int i = 0; i < N + 2; i++)
{
for (int j = 0; j < N + 2; j++)
{
printf("%c", board2[i][j]);
}
printf("\n");
}
}
//检测某个位置是不是可以放置皇后
int check2(int i, int j)
{
int ret = 1;
for (int p = 0; p < 3; p++)
{
int ni = i;
int nj = j;
while (ret && (board2[ni][nj] != '#'))
{
ni = ni + pos2[p].xpos;
nj = nj + pos2[p].ypos;
ret = ret && (board2[ni][nj] != '*');
}
}
return ret;
}
//找出所有的皇后
void find2(void)
{
//行
for (int i = 1; i <= N;)
{
int flag = 1;
for (int j = QueenPos2[i]; j <= N;j++)
{
//检测一下可不可以安置一个皇后
if (check2(i,j))
{
QueenPos2[i] = j;
board2[i][j] = '*';
flag = 0;
break;
}
}
//如果flag==1?表示没找到,否则找到
if (flag)
{
i--;
board2[i][QueenPos2[i]] = ' ';
QueenPos2[i]++;
}
else
{
i++;
}
getchar();
}
display2();
}
#include <iostream>
using namespace std;
bool place(int *x, int k)
{
for(int i=1;i<k;i++)
{
if((x[i]==x[k]) || (abs(x[i]-x[k])==abs(i-k)))
return false;
}
return true;
}
void n_queens(int n)
{
int *x = new int[n+1];
for(int i=0;i<n+1;++i) x[i]=0;
int k=1;//k表示当前搜索的行数,从第1行开始
x[1]=0;//x[1]是解向量第一个元素,为跟以后的循环匹配,先赋值给0,其实是从1开始的
while(k>0)//控制行,只要大于0,证明搜索在第0行以下进行
{
//start 找到符合条件的列
x[k]=x[k]+1;//从下一列开始,因为不能同列
while((x[k]<=n)&&(!place(x,k)))//找到下一个满足条件的列
x[k]=x[k]+1;//后移一列
//end 找到符合条件的列
if(x[k]<=n)//有符合条件的列
{
if(k==n)break;//搜索完成,跳出循环
else//搜索没有完成(得到的是部分解)
{
k=k+1;//搜索下一行
x[k]=0;//下一行的x[k]初始化为0
}
}
else//没有符合条件的列了
{
x[k]=0;//恢复x[k]为0
k=k-1;//回溯到上一行
}
}
for(int i=1;i<n+1;++i)
cout<<x[i]<<" ";
cout<<endl;
delete[] x;
}
//每个函数的功能是处理一行,也就是填写x[i],然后决定是继续填写x[i+1]还是
//回溯填写x[i-1]
bool r_n_q(int* x,int i,int n)
{
if(i<1)return false;//回溯到根节点了,证明无解
x[i]=x[i]+1;//因为上一个x[i]是死节点了,所以查询下一个
while((x[i]<=n) && (!place(x,i)))
x[i]=x[i]+1;//找到下一个满足条件的节点,或者扫描完整个行
if(x[i]<=n)//找到符合条件的节点了
{
if(i==n)return true;//已经是第n行了,也就是x数组填充成功了
else//还没填充完,得到的是部分解,继续填写下一行
{
x[i+1]=0;//下一行从0开始,因为后面要加1
r_n_q(x,i+1,n);//调用函数填写第i+1行
}
}
else//没有找到符合条件的节点,也就是这一行扫描完了,要回溯到上一行了
{
r_n_q(x,i-1,n);//回溯,搜索上一行
}
}
void recursive_n_queens(int n)
{
int *x = new int[n+1];
for(int i=0;i<n+1;++i) x[i]=0;
if(r_n_q(x,1,n))
{
for(int i=1;i<n+1;++i)
cout<<x[i]<<" ";
cout<<endl;
}
else
cout<<n<<"皇后问题无解!"<<endl;
delete[] x;
}
int main()
{
for(int i=1;i<15;++i)
{
n_queens(i);
recursive_n_queens(i);
}
system("pause");
return 0;
}