经典的回溯法题目
代码:
#include"stdio.h"
#define N 8 //最低值可以到4
int count;
int cb[N][N]; //Checkerboard 棋盘
//检查行列对角线是否有放棋子
int check(int x, int y) {
int i;
for (i = 0; i < N; i++)//行列检查
if (cb[i][y] == 1 || cb[x][i] == 1)
return 0;
//由于是一行一行往下放棋子,故只需检查该棋子以上的对角线即可
for (i = 1; x - i >= 0 && y - i >= 0; i++)//主对角线检查
if (cb[x - i][y - i] == 1)
return 0;
for (i = 1; x - i >= 0 && y + i < N; i++)//副对角线
if (cb[x - i][y + i] == 1)
return 0;
return 1;
}
//输出
void out(){
int i, j;
printf("方案%d:", count);
for (i = 0; i < N; i++){
for (j = 0; j < N; j++){
if (cb[i][j] == 1){
printf("%d ", j + 1);
break;
}
}
}
printf("\n");
}
void dfs(int x, int y) {
int i;
if (x == N) {//越界即为出口
count++;
out();
}
else {
//1~N个位置进行摆放
for (i = 0; i < N; i++) {
//(x,i)行列主副对角及本身位置没有放置棋子
if (check(x, i) && cb[x][i] == 0) {
cb[x][i] = 1;//放置棋子(添加标记)
dfs(x + 1, i);//放置棋子后进入下一行
cb[x][i] = 0;//拿起棋子(去除标记,回溯 )
}
}
}
}
int main() {
count = 0;
dfs(0, 0);
//printf("%d\n",count);
return 0;
}