N皇后问题(万恶的搜索入门)

        听我朋友说这个叫做深搜来着....

        反正我也不知道,你们就凑活着看吧。OVO相信聪明的泥萌一定能够看得懂的。

        这道题的原题在杭电oj的2553,链接我就放在这里啦!杭电oj 2553,N皇后问题

        好那么下面我们看一下这个基本的思路啊,这个题目说白了就是要进行搜索,但是你懂搜索这东西说白了就是优雅地暴力,我们发现每一个皇后放下之后,它那一行和一列都已经不能再放棋子了,所以嘛,我们可以根据这个特点省下不少时间呢。直接就可以建立两个数组来储存每一行和每一列的状态啦,当然这个也是可以优化的,你可以把它写在你的棋盘数组里面,虽然说是优化,但是容易把自己搞迷糊,不活就是少写了两行代码而已,所以我们就不再那么写辣~

        然后我们最重要的工具就是写一个函数检查一下这一点可不可以放下你的皇后,做到这些之后,大体的思路就出来辣~

  1.         第一列从上到下开始遍历,如果某一点可以放下皇后则放下,标记本点以及行列。
  2.         搜索下一列。
  3.         如果某次搜索发现已经搜索出界,那么及获得一个可行解,答案加一。
  4.         重复上述过程。

        基本上就是一个递归过程辣,没什么难的。这道题里面注意一下不要弄出来超时,尽管只有十种可能的测试数据,但是如果人家一直重复地问你,你总不能一遍一遍计算,所以,提前计算出来所有的可能性比较好。当然这一题里面因为数据量较小所以可以这么做

        下面就是泥萌如狼似虎渴求的代码辣!OVO

#include
#include
int row[12], col[12];//前者为行,后者为列
int dis[12][12];//棋盘,1-0
int ans;
int num[10];
int n;//规模
	  //检查函数,检查一个点可不可以放皇后
bool check(int x, int y)
{
	int s, t;
	if (row[x] || col[y])
	{
		return false;
	}
	for (s = x + 1, t = y + 1; s < n&&t < n; s++, t++)
	{
		if (dis[s][t])
		{
			return false;
		}
	}
	for (s = x - 1, t = y + 1; s >= 0 && t < n; s--, t++)
	{
		if (dis[s][t])
		{
			return false;
		}
	}
	for (s = x + 1, t = y - 1; s < n&&t >= 0; s++, t--)
	{
		if (dis[s][t])
		{
			return false;
		}
	}
	for (s = x - 1, t = y - 1; s >= 0 && t >= 0; s--, t--)
	{
		if (dis[s][t])
		{
			return false;
		}
	}
	return true;
}

void dfs(int s)//深度搜索啦
{
	if (s == n)//如果搜索出棋盘,就可以直接结果加一
	{
		ans++;
		return;
	}
	for (int i = 0; i < n; i++)//反之就是继续往下找啦
	{
		if (check(i, s))//检查可不可以放棋子啦
		{
			row[i] = col[s] = dis[i][s] = 1;//这里标记当前棋子的行列都已经被占据
			dfs(s + 1);//往下找~
			row[i] = col[s] = dis[i][s] = 0;//因为这一列检查完了,所以就要把标记撤掉咯
		}
	}
}
int main()
{ 
	for (int i = 1; i < 11; i++)
	{
		n = i;
		ans = 0;
		memset(row, 0, sizeof(row));
		memset(col, 0, sizeof(col));
		memset(dis, 0, sizeof(dis));
		dfs(0);
		num[i] = ans;
	}
	int s;
	while (scanf("%d", &s) != EOF, s)
	{
		printf("%d\n", num[s]);
	}
	return 0;
}

        喜欢别忘记点赞!

你可能感兴趣的:(ACM,题解)