洛谷P1219 八皇后 ----(C语言 + 详细注释)

//本题是典型的搜索题,每一行有n种情况,一行行的枚举即可。

下面是我AC的代码:

#include<stdio.h>
#include<math.h>
int n, cnt, a[15], flag, times;        //数组a储存每一行棋子的列数
times = 3;

void dfs(int x) {           //参数x为现在到了第几行
	int i, j;
	if (x == n + 1) {        //x == n + 1时说明n行已经枚举完了
		if (times) {          //判断3次输出机会是否用完
			for (int i = 1; i <= n; i++)
				printf("%d ", a[i]);        //输出每行棋子所在的列数
			printf("\n");
			times--;
		}
		cnt++;              //满足情况的次数+1
		return;
	}
	for (j = 1; j <= n; j++) {              //枚举这一行的n列
		flag = 0;
		for(i = 1; i < x; i++)
			if (abs(a[i] - j) == abs(i - x) || a[i] == j) {    //因为与对角线平行的线斜率为1或-1,那么线上两点的横、纵坐标之差的绝对值相等,后者是判断是否和上面的棋子在同一列
				flag = 1;        //如果这一行目前枚举的纵坐标不符题意,标记为1,跳出循环
				break;
			}
		if (!flag) {            //!flag等价于 flag == 0,即枚举的纵坐标符和题意
			a[x] = j;           //把这个纵坐标加入数组a中
			dfs(x + 1);        //继续下一行
		}

	}

}




int main() {
	scanf("%d", &n);
	dfs(1);            //从第一行开始
	printf("%d", cnt);         //输出满足的种类数

	return 0;
}

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值