八皇后的问题

lkjasdf9909 2015-11-27 10:11:10

#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();
}



程序执行的时候,最后坐标会出现负数,中断,
逻辑应该没什么问题把
...全文
189 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
logiciel 2015-11-28
  • 打赏
  • 举报
回复
LZ程序第108行i--将导致i<1.
flying_music 2015-11-28
  • 打赏
  • 举报
回复
不知道你的思路,代码很难看懂啊,这是以前学的时候写的,有循环和递归两个版本,你可以对照看一下,没有画图,只生成了结果数组
#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;
}

69,374

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧