给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。
输入格式:
输入的第一行为一个整数n,表示棋盘的大小。 接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。
输出格式:
输出一个整数,表示总共有多少种放法。
输入样例1:
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
输出样例1:
2
输入样例2:
4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1
输出样例2:
0
递归回溯。
代码:
#include <stdio.h> #include <stdlib.h> int mp[10][10],lay[10],n; int ans[100][8],ant; int temp[8],num; int check(int k,int v) { for(int i = 0;i < k;i ++) { if(temp[i] == v)return 0; if(abs(temp[i] - v) == k - i)return 0; } return 1; } int dif(int a,int b) { for(int i = 0;i < n;i ++) { if(ans[a][i] == ans[b][i])return 0; } return 1; } void que(int k){ if(k == n) { for(int i = 0;i < n;i ++) { ans[ant][i] = temp[i]; } ant ++; return; } for(int i = 0;i < n;i ++) { if(mp[k][i] && check(k,i)) { temp[k] = i; mp[k][i] = 0; que(k + 1); mp[k][i] = 1; } } } int main() { scanf("%d",&n); for(int i = 0;i < n;i ++) { for(int j = 0;j < n;j ++) { scanf("%d",&mp[i][j]); } } que(0); for(int i = 0;i < ant;i ++) { for(int j = 0;j < i;j ++) { if(dif(i,j))num ++; } } printf("%d",num * 2); }