当前位置: 首页> 娱乐> 明星 > 宝宝发烧反反复复什么原因导致的_宣传海报制作app_山西网络营销外包_商丘网站推广公司

宝宝发烧反反复复什么原因导致的_宣传海报制作app_山西网络营销外包_商丘网站推广公司

时间:2025/7/9 12:08:32来源:https://blog.csdn.net/kwslo/article/details/144434235 浏览次数:0次
宝宝发烧反反复复什么原因导致的_宣传海报制作app_山西网络营销外包_商丘网站推广公司

本题是一道dfs的题目()()感觉主要的困惑点在于对角线的判断(我刚开始还想遍历

题目:

题目很简短,清晰易懂,就是要找到全部的能使n个棋子在不同行不同列并且也不会在同一对角线或与对角线平行的线上的排列方法,并输出按字典序排列的前三种方法

乍一看,最先想到的就是放个二维数组每次遍历,但又会很快的叉掉(

于是,我们采取搜寻列、两个方向的对角线的方法而不是遍历数组来判断当前位置能否放棋子

代码如下:

#include <stdio.h>int n = 0; //用于记录棋盘大小
int col[14] = { 0 };//用于判断当前列是否有棋子
int left_diag[39] = { 0 };//用于判断次对角线(对于某个位置来说)
int right_diag[26] = { 0 };//用于判断主对角线(对于某个位置来说)
int ans[15] = { 0 }; //答案数组
int count = 0; //记录摆放数;/*对于left_diag与right_diag这两个数组的运作方式的解答:
* 若有棋盘
*    1 2 3 4
*  1 0 0 0 0
*  2 0 0 0 0
*  3 0 0 0 0
*  4 0 0 0 0
* 不难看出,对于一个向右下的对角线,其上元素的行指标减列指标总为定值
* 那么,对于一个确定的棋盘,该方向对角线的‘定值’的最大值会在最左边那条对角线取得,即行指标为n,列指标为1,定值也就是n-1
* 而在右边的对角线,该定值为负,所以我们需要给一个偏移量,让所有的定值映射到正数,即+n 处理来标记每条对角线
* 于是,我们的right_diag数组,应该给26的大小
* 类似的,我们也可以得出left_diag应该给出39的大小;
*///核心:深搜
void dfs(int row)
{//搜到一种摆放方式if (row == n + 1){//计数器+1count++;//打印前三个摆放方式if (count <= 3){for (int i = 1; i < n + 1; i++){printf("%d ", ans[i]);}printf("\n");}return;}//搜索每一列是否可能有答案for (int i = 1; i < n + 1; i++){//如果当前列没有棋子并且两个方向的对角线也没有棋子if (!col[i] && !left_diag[i + row] && !right_diag[row - i + n]){//标记col[i] = 1; left_diag[i + row] = 1; right_diag[row - i + n] = 1;//放入答案ans[row] = i;//搜索下一行dfs(row + 1);//清除标记col[i] = 0; left_diag[i + row] = 0; right_diag[row - i + n] = 0;//清除答案ans[row] = 0;}}return;
}int main()
{scanf("%d", &n);dfs(1);printf("%d", count);return 0;
}

最后,附上AC!!!

关键字:宝宝发烧反反复复什么原因导致的_宣传海报制作app_山西网络营销外包_商丘网站推广公司

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: